SQL事务死锁
我有一个名为table_1(SQL Server 2014)的表。它有两列(名称、id) 我想在两个单独的连接中同时运行以下脚本:SQL事务死锁,sql,sql-server,transactions,deadlock,Sql,Sql Server,Transactions,Deadlock,我有一个名为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_
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
及
它们都放在单个事务和单个进程中。
我很抱歉,但为什么会死锁。
我所知道的死锁是当我们有两个资源和两个事务时,如果Transaction1锁定resource1,同时Transaction2锁定resource2,他们需要锁定其他资源(Transaction1锁定resource2,Transaction2锁定resource1)。但它们都不能锁定第二个资源。
在这种情况下,db引擎会终止其中一个事务,并出现死锁异常。您使用的是哪种dbms?SQL server 2014您首先为什么要这样做?为什么是
而?此外,由于您获取MAX
值,然后尝试插入该值,因此上述操作很容易导致其他问题。在获取MAX
和插入它之间的(很短)时间内,另一个事务可能很容易插入一个值并导致重复键。这闻起来像是一场灾难。通常,试图重塑自己只会落泪。要让这样的方案发挥作用,您需要精确的锁定(而不仅仅是在上面打上SERIALIZABLE
),这种锁定即使能够发挥作用,也很容易破坏性能。您可能会发现,如果您开始混合使用标识插入,则只有完整表锁或自定义应用程序锁才能始终如一地工作。当然,如果您使用的是@JeroenMostert提到的这类锁,您将无法同时运行2个事务。
insert into Table_1