同时执行的查询死锁

时间:2011-04-13 08:07:40

标签: sql sql-server-2008

我有一个存储过程执行以下操作(简化):

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

我的问题是,当两个或多个用户同时执行此操作时,我会遇到死锁。现在据我所知,当我在proc中进行第一次选择时,应该在tbl中创建一个锁定。如果在第一个程序仍在执行时调用第二个程序,它应该等待它完成吗?

目前导致僵局,任何想法?

2 个答案:

答案 0 :(得分:3)

insert查询需要与select不同的锁定。 select的锁定阻止了第二个insert,但它不会阻止第二个select。因此,这两个查询都可以从select开始,但它们都会阻止另一个insert

您可以通过询问第一个查询来锁定整个表来解决此问题:

SET @intNo = (SELECT MAX(intNo) + 1 FROM tbl with (tablockx))
                                             ^^^^^^^^^^^^^^^

这将使第二个交易的select等待完成第一笔交易。

答案 1 :(得分:1)

使它更简单,因此你有一个陈述而没有交易

--BEGIN TRANSACTION  not needed

INSERT INTO tbl(intNo)
OUTPUT INSERTED.intNo
SELECT MAX(intNo) + 1 FROM tbl WITH (TABLOCK)

--COMMIT TRANSACTION not needed

虽然,你为什么不使用IDENTITY ......?