我有一个执行以下操作的存储过程(简化):
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
BEGIN TRANSACTION
DECLARE @intNo int
SET @intNo = (SELECT MAX(intNo) + 1 FROM tbl)
INSERT INTO tbl(intNo)
Values (@intNo)
SELECT intNo
FROM tbl
WHERE (intBatchNumber = @intNo - 1)
COMMIT TRANSACTION
我的问题是,当两个或更多用户同时执行此操作时,我会遇到死锁。现在,据我了解,当我在过程中进行第一次选择时,这应该在 tbl 中创建一个锁。如果在第一个过程仍在执行时调用第二个过程,则应该等待它完成,对吗?
目前这导致了僵局,有什么想法吗?
最佳答案
insert
查询需要与 select
不同的锁。 select
的锁会阻止第二个 insert
,但不会阻止第二个 select
。因此,两个查询都可以从 select
开始,但它们都会阻塞对方的 insert
。
您可以通过要求第一个查询锁定整个表来解决此问题:
SET @intNo = (SELECT MAX(intNo) + 1 FROM tbl with (tablockx))
^^^^^^^^^^^^^^^
这将使第二个事务的 select
等待第一个事务完成。
关于sql - 同时执行的查询出现死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5646189/