首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用于更新的行锁

用于更新的行锁
EN

Stack Overflow用户
提问于 2019-04-15 21:04:47
回答 1查看 57关注 0票数 0

有人能为我证实这一点吗。我需要能够在行中的一个字段中写入一个“所有权”值(谁拥有该记录),并且需要它成为第一个选择要更新的行的人,并忽略任何进一步的选择,直到该行可用于写入...

我的事务将是:

代码语言:javascript
复制
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的帮助下)这将允许我锁定行,检查其中是否有值,如果没有,则写入一个值,如果有,则退出。

这有意义吗?

提前谢谢你..

德里克。

EN

回答 1

Stack Overflow用户

发布于 2019-04-15 22:56:34

除非您想通过产生死锁来处理争用,否则不要为此使用SERIALIZABLE。SERIALIZABLE将在第一个查询中获取并持有共享(S)锁,因此并发事务将读取该行,并在它们都试图更新该行时进入死锁。一个将被杀死;另一个将成功,并且SERIALIZABLE语义被保留。

相反,您应该在读取目标行时对其设置一个限制性锁。

例如:

代码语言:javascript
复制
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列。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55689829

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档