SQL事务死锁

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_

我有一个名为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

它们都放在单个事务和单个进程中。 我很抱歉,但为什么会死锁。 我所知道的死锁是当我们有两个资源和两个事务时,如果Transaction1锁定resource1,同时Transaction2锁定resource2,他们需要锁定其他资源(Transaction1锁定resource2,Transaction2锁定resource1)。但它们都不能锁定第二个资源。
在这种情况下,db引擎会终止其中一个事务,并出现死锁异常。

您使用的是哪种dbms?SQL server 2014您首先为什么要这样做?为什么是
?此外,由于您获取
MAX
值,然后尝试插入该值,因此上述操作很容易导致其他问题。在获取
MAX
和插入它之间的(很短)时间内,另一个事务可能很容易插入一个值并导致重复键。这闻起来像是一场灾难。通常,试图重塑自己只会落泪。要让这样的方案发挥作用,您需要精确的锁定(而不仅仅是在上面打上
SERIALIZABLE
),这种锁定即使能够发挥作用,也很容易破坏性能。您可能会发现,如果您开始混合使用标识插入,则只有完整表锁或自定义应用程序锁才能始终如一地工作。当然,如果您使用的是@JeroenMostert提到的这类锁,您将无法同时运行2个事务。
insert into Table_1