有人能为我证实这一点吗。我需要能够在行中的一个字段中写入一个“所有权”值(谁拥有该记录),并且需要它成为第一个选择要更新的行的人,并忽略任何进一步的选择,直到该行可用于写入...
我的事务将是:
BEGIN TRANSACTION
Declare @OwnerField Varchar(20)
SET @OwnerField = SELECT OwnerField
FROM Table
WHERE RecordID = 2
IF @OwnerField IS NULL -- Can own
BEGIN
UPDATE Table
SET OwnerField = 'John Smith'
WHERE RecordID = 2
END
END TRANSACTION据我所知(在Google的帮助下)这将允许我锁定行,检查其中是否有值,如果没有,则写入一个值,如果有,则退出。
这有意义吗?
提前谢谢你..
德里克。
发布于 2019-04-15 22:56:34
除非您想通过产生死锁来处理争用,否则不要为此使用SERIALIZABLE。SERIALIZABLE将在第一个查询中获取并持有共享(S)锁,因此并发事务将读取该行,并在它们都试图更新该行时进入死锁。一个将被杀死;另一个将成功,并且SERIALIZABLE语义被保留。
相反,您应该在读取目标行时对其设置一个限制性锁。
例如:
BEGIN TRANSACTION
Declare @OwnerField Varchar(20)
SET @OwnerField = SELECT OwnerField
FROM Table with (UPDLOCK,HOLDLOCK)
WHERE RecordID = 2
IF @OwnerField IS NULL -- Can own
BEGIN
UPDATE Table
SET OwnerField = 'John Smith'
WHERE RecordID = 2
END
END TRANSACTION(UPDLOCK,HOLDLOCK)为您提供了与SERIALIZABLE隔离级别相同的范围锁定保护,但使用了限制性锁,因此多个事务将在SELECT上阻塞。第二个读取器将阻塞,直到第一个读取器提交,并看到更新的OwnerField列。
https://stackoverflow.com/questions/55689829
复制相似问题