开发者

Deadlock on query that is executed simultaneously

开发者 https://www.devze.com 2023-02-25 00:45 出处:网络
I\'ve got a stored procedure that does the following (Simplified): SET TRANSACTION ISOLATION LEVEL REPEATABLE READ

I've got a stored procedure that does the following (Simplified):

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

My issue is that when two or more users execute this at the same time I am getting deadl开发者_JAVA百科ocks. Now as I understand it the moment I do my first select in the proc this should create a lock in tbl. If the second procedure is then called while the first procedure is still executing it should wait for it to complete right?

At the moment this is causing a deadlock, any ideas?


The insert query requires a different lock than the select. The lock for select blocks a second insert, but it does not block a second select. So both queries can start with the select, but they both block on the other's insert.

You can solve this by asking the first query to lock the entire table:

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

This will make the second transaction's select wait for the complete first transaction to finish.


Make it simpler so you have one statement and no transaction

--BEGIN TRANSACTION  not needed

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

--COMMIT TRANSACTION not needed

Although, why aren't you using IDENTITY...?

0

精彩评论

暂无评论...
验证码 换一张
取 消