同时执行的查询死锁

问题描述

| 我有一个执行以下操作(简化)的存储过程:
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中创建一个锁。如果在第一个过程仍在执行时调用第二个过程,则应等待第二个过程完成,对吗? 目前这造成了僵局,有什么想法吗?     

解决方法

insert
查询所需要的锁与
select
不同。
select
的锁定会阻止第二个
insert
,但不会阻止第二个
select
。因此,两个查询都可以以ѭ2开始,但是它们都阻塞在另一个s1上。 您可以通过要求第一个查询锁定整个表来解决此问题:
SET @intNo = (SELECT MAX(intNo) + 1 FROM tbl with (tablockx))
                                             ^^^^^^^^^^^^^^^
这会使第二笔交易的ѭ2等待第一笔交易的完成。     ,使它更简单,使您只有一条语句而无需事务
--BEGIN TRANSACTION  not needed

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

--COMMIT TRANSACTION not needed
虽然,为什么不使用IDENTITY ...?