我有一个带有select和update的存储过程。我想防止多个用户同时执行它,所以我不会根据错误的选择进行更新。 我该如何锁定它? 我已经阅读了各种解决方案(事务隔离,xlock),但我无法弄清楚我真正想要的是什么,以及如何做到这一点。
答案 0 :(得分:4)
最简单的方法是忘记数据锁,但查看sp_getapplock以通过代码控制访问
BEGIN TRY
EXEC sp_getapplock ...
SELECT ...
UPDATE ...
EXEC sp_releaseapplock
END TRY
...
用OUTPUT子句和明智地使用ROWLOCK这样的东西说,UPDLOCK很有可能UPDATE和SELECT可以是一个语句
答案 1 :(得分:0)
使用SELECT
查询中的XLOCK表提示:
CREATE TABLE [X]([x] INT NOT NULL)
GO
INSERT [X]([x]) SELECT 0
GO
CREATE PROCEDURE [ATOMIC]
AS
BEGIN
BEGIN TRAN
DECLARE @x INT = (
SELECT [x]
FROM [X] (XLOCK)
) + 1
UPDATE [X] SET [x] = @x
COMMIT TRAN
END
GO
然后您可以通过运行
来测试它EXEC [ATOMIC]
GO 10000
同时来自不同的会话。您可以使用
进行测试SELECT [x] FROM [X]
该值应该是您运行的会话数的10 000倍。如果数字小于预期,则表示没有原子读取+写入,或者由于死锁而导致某些SPID被杀死。