首页 > 解决方案 > SQL 事务死锁

问题描述

我有一个名为 Table_1 (SQL Server 2014) 的表。它有两列(名称,id)

我想同时在两个单独的连接中运行以下脚本:

while 1 = 1
begin
begin try
    SET TRANSACTION ISOLATION LEVEL Serializable; 
        begin tran

        declare @maxId int = 0
        select @maxId = MAX(Id) + 1 from [dbo].[Table_1] 
        print(@maxId)

        set identity_insert [dbo].[Table_1] on
            INSERT INTO [dbo].[Table_1] (Id,[Name])
            VALUES (@maxId,'11')
        set identity_insert [dbo].[Table_1] off

commit tran
end try
begin catch

IF(@@TRANCOUNT > 0)
rollback tran

    print ( ERROR_MESSAGE())
    print ( ERROR_SEVERITY())
    print ( ERROR_STATE())
 
end catch 

end

在这个脚本中,我在 while 循环内的表中插入了行。当此脚本的两个实例运行时,我收到以下错误:

事务(进程 ID 62)与另一个进程在锁资源上死锁,并已被选为死锁牺牲品。重新运行事务。

为什么不同连接中的不同事务不互相等待,而我们得到一个死锁错误?


我已经更正了我的问题,以便更好地理解我的意思。实际上,我不使用while。我只是模拟对数据库的高请求(在不同的进程中)以检查一致性并检查并发问题。

查询的模棱两可的部分是为什么死锁?。一个进程有两个动作:

select from Table_1

insert into Table_1

它们都放在单个事务和单个进程中。我预计超时,但为什么会出现死锁。我对死锁的了解是,当我们有两个资源和两个事务时,如果 Transaction1 锁定 resource1,同时 Transaction2 锁定 resource2,他们需要锁定其他资源(Transaction1 锁定 resource2,Transaction2 锁定 resource1)。但是他们俩,都无法锁定第二资源。在这种情况下,数据库引擎会终止其中一个带有死锁异常的事务。

标签: sqlsql-servertransactionsdeadlock

解决方案


推荐阅读