我有几个存储过程(添加和删除),它们运行一些选择,插入,删除和删除。一些表的更新。这些看起来很好。
这些过程中的每一个都使用TRANSACTION。 我在对数据进行任何更改之前开始事务处理,并且接近proc的结尾。
IF @@TRANSCCOUNT > 0
COMMIT TRANSACTION @transName;
在Add和Remove过程中,在TRANSACTION中,我调用另一个存储过程(Adjust)来更新一个保持运行总值的表。 我发现这是不同步.....
这是proc的主体......
INSERT INTO L2(ProductId, LocationId, POId, StockMoveId, BasketId, OrderId, AdjusterValue, CurrentValue)
SELECT TOP 1
@ProductId, @LocationId, null, null, @BasketId, null, @Value, (CurrentValue + @Value)
FROM L2
WHERE 1=1
AND LocationId = @LocationId
AND ProductId = @ProductId
ORDER BY Id Desc
ProductId,LocationId,StockMoveId和OrderId都是相关表的外键,但允许空值,因此只需要使用实际值填充适当的值。
19应该已经添加到324个新的总数343,但是,你可以看到它似乎已被添加到300和319插入。
...问题 这实际上是在调用存储过程中开始的事务中。
我该如何预防这种情况?
我尝试使用MAX来获得正确的行以尝试加速,但执行计划并不像简单的TOP那样具有成本效益。 ID,btw是一个标识列和PKey。
我是否需要锁定表格,如果我使用其他进程调用调整等待或是否会出错。
非常感谢任何帮助。
更多信息.... 我一直在进行实验,看起来唯一能够按照预期一致工作的解决方案是将Id列作为INT字段,并在INSERT上自行增加它。 这对我来说并不合适,对我来说,为什么IDENTITY列n似乎没有应对,这是没有意义的。
我已经尝试过发布的Identity列解决方案,序列和自己递增ID
答案 0 :(得分:0)
经过大量搜索,试验我SEEM以获得一个现在非常强大的解决方案。 我现在将ID作为一个简单的INT列,我自己通过为每个新插入获取MAX + 1来管理ID。
我现在将Adjust proc的主体包装在自己的Transaction中,并使用以下内容获取下一个ID .....
DECLARE @trxNam Varchar(10) = 'tranNextId';
DECLARE @newId INT;
DECLARE @currentLevelId INT;
BEGIN TRANSACTION @trxNam;
SELECT @newId = MAX(id) + 1 FROM L2 WITH(updlock,serializable);
然后我使用@newId和COMMIT命名事务进行插入。 我有一个场景设置,我有许多Win32Apps,因为间歇性的PKEY违规而导致我的API 100次失败。 现在它没有。
快乐的日子! 我仍然想看看我是否可以再次拥有一个标识列并在adjust proc中使用Transaction ...我认为这样会更清晰。