sql - TABLOCKX 与 SERIALIZABLE

标签 sql sql-server tsql

我有一系列需要原子运行的 T-SQL 查询。 (见下文)...目的是允许 1 个用户一次检索单个唯一行,并防止其他用户同时检索同一行。

到目前为止,我已经看到了两种可能的解决方案。 1) 表提示(HOLDLOCK、TABLOCKX)和 2)事务隔离级别(SERIALIZABLE)...

我的问题:

  1. 哪个选项更好?

  2. 还有其他/更好的解决方案吗?

DECLARE @recordId int;

SELECT @recordId = MIN([id])
FROM Exceptions
WHERE [status] = 'READY';

UPDATE Exceptions
SET [status] = 'PROCESSING',
    [username] = @Username
WHERE [id] = @recordId;

SELECT *
FROM Exceptions
WHERE [id] = @recordId;

最佳答案

在这种情况下,

  • HOLDLOCK = SERIALIZABLE = 持续时间、并发
  • TABLOCKX = 独占表锁

这两个概念不同,也不是您想要的。

做你想做的事,到avoid race conditions ,您需要强制非阻塞(READPAST)独占(UPDLOCK)行级(ROWLOCK)锁。您还可以使用 OUTPUT 子句使其成为原子的单个语句。这可以很好地扩展。

UPDATE
    E
SET
   [status] = 'PROCESSING', [username] = @Username
OUTPUT
   INSERTED.*
FROM
   (
    SELECT TOP 1 id, [status], [username]
    FROM Exceptions (ROWLOCK, READPAST, UPDLOCK)
    WHERE [status] = 'READY'
    ORDER BY id
   ) E

总的来说,锁有3个方面

  • 粒度 = 锁定的内容 = 行、页、表(PAGLOCK、ROWLOCK、TABLOCK)
  • 隔离级别 = 锁定持续时间、并发性(HOLDLOCK、READCOMMITTED、REPEATABLEREAD、SERIALIZABLE)
  • 模式 = 共享/独占(UPDLOCK、XLOCK)

还有

  • “组合”,例如NOLOCK、TABLOCKX

关于sql - TABLOCKX 与 SERIALIZABLE,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4924861/

相关文章:

sql - 判断图是否有环

sql-server - SQL Server Management Studio - 网格结果另存为 .CSV - 如何输出文本而不是 UTF-16 (Unicode)

.net - 将XML插入SQL Server时出现 "unable to switch the encoding"错误如何解决

sql-server - Node.js socket.io sql server 推送通知

sql-server - TSQL:如何检查列是否启用全文?

entity-framework - 如何创建 SQL Server 系统表

mysql - 如何将此 SQL 转储导入到 PhpMyAdmin 中而不出现此错误?

sql - 计算季度开始日期

SQL查询如何计算单行中的不同值

sql-server - 如何在存储过程中循环遍历表?