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;
在这种情况下,
这两个概念是不同的,都不是你想要的。
要做你想做的事情,为了避免竞争条件,你需要强制一个非阻塞(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也不需要序列化,他们也不会实际工作。 我建议你继续使用表格作为队列来进行关于可能和不可能的部分讨论。 其要点是: