假设您有以下代码(请忽略这很糟糕):
BEGIN TRAN;
DECLARE @id int
SELECT @id = id + 1 FROM TableA;
UPDATE TableA SET id = @id; --TableA must have only one row, apparently!
COMMIT TRAN;
-- @id is returned to the client or used somewhere else
在我看来,这不能正确地管理并发。仅仅因为您有一笔交易并不意味着其他人不会获得与您获得更新语句之前相同的值。
现在,将代码保持原样(我意识到这可以更好地作为单个语句处理,甚至可以使用自动增量/标识列更好地进行处理),有什么确定的方法可以使其正确处理并发并防止允许两个客户端获得相同竞争条件的竞争条件。 id值?
我非常确定,将WITH (UPDLOCK, HOLDLOCK)
SELECT 添加到SELECT即可。该SERIALIZABLE事务隔离级别(因为它拒绝任何人阅读你做了什么,直到移植是在将似乎工作,以及UPDATE:这是假见马丁的答案)。真的吗?他们俩会平等地工作吗?是一个比另一个更好的选择吗?
想象一下,做比ID更新更合法的事情-基于需要更新的读取进行一些计算。可能涉及许多表,其中一些将要写入,而有些则不会。最佳做法是什么?
写完这个问题后,我认为锁定提示会更好,因为那样的话,您只锁定了所需的表,但是我很感谢任何人的投入。
PS:不,我不知道最佳答案,并且确实希望得到更好的理解!:)
update
基于过时的数据进行发行?如果是后者,则可以使用rowversion
column来检查要读取的行自读取以来是否未更改。