我有一个自动递增的主键 OrderHeaderID,但我还需要根据订单下达的公司自动递增 OrderNumber。
当前策略:(在表中插入语句)
(SELECT MAX(OrderNumber) + 1 FROM OrderHeader WHERE CompanyID = @CompanyID)
问题:一旦我开始用一定的音量进行测试,我就开始出现重复的键错误:
表订单标题:
OrderHeaderID CompanyID OrderNumber
1 1 10000
2 1 10001
3 1 10002
4 2 10000
5 2 10001
6 2 10002
最佳答案
要解决并发问题,您必须提高 SELECT
语句的隔离级别,然后在同一事务内执行 INSERT
。
每个 RBDMS 的具体语法会有所不同,但这里有一个使用 Sql Server 的示例:
BEGIN TRANSACTION
DECLARE @OrderNumber INT
SELECT @OrderNumber = MAX(OrderNumber) + 1
FROM OrderHeader WITH (XLOCK)
WHERE CompanyID = @CompanyID
INSERT... (@OrderNumber)
COMMIT
这会在 SELECT
语句期间读取的行上放置一个独占锁,这将阻止该例程的另一个实例同时运行。相反,第二个实例将被阻塞,直到原始进程执行 INSERT 和 COMMIT,此时第二个实例将继续读取并锁定新生成的值。
关于sql - 自动递增订单号(一张表多个公司),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12414352/