TABLOCKX与SERIALIZABLE

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

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

我的问题:

  • 哪个选项更好?

  • 还有其他更好的解决方案吗?

  • 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 =独占表格锁
  • 这两个概念是不同的,都不是你想要的。

    要做你想做的事情,为了避免竞争条件,你需要强制一个非阻塞(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
    

    一般来说,锁具有三个方面

  • 粒度=什么被锁定=行,页面,表格( PAGLOCK, ROWLOCK, TABLOCK
  • 隔离级别=锁定持续时间,并发性( HOLDLOCK, READCOMMITTED, REPEATABLEREAD, SERIALIZABLE
  • 模式=共享/排他性( UPDLOCK, XLOCK
  • “结合”,例如NOLOCK, TABLOCKX

  • 您正在描述典型的队列处理,既不需要tablockx也不需要序列化,他们也不会实际工作。 我建议你继续使用表格作为队列来进行关于可能和不可能的部分讨论。 其要点是:

  • 选择适当的集群密钥(关键!)
  • 使用OUTPUT子句
  • 使用READPAST
  • 链接地址: http://www.djcxy.com/p/32839.html

    上一篇: TABLOCKX versus SERIALIZABLE

    下一篇: When UPDLOCK get released in SQL server?