在sql server发生死锁时,WHICH事务将被中止

时间:2014-04-09 15:08:07

标签: sql transactions sql-server-2012 deadlock rollback

当sql server发生死锁时,哪些事务将被中止。我的意思是sql server的计划决定应该杀死哪些事务!

考虑下面的两个交易

交易A

begin transaction
    update Customers set LastName = 'Kharazmi'
    waitfor delay '00:00:5'; -- waits for 5 second
    update Orders set OrderId=13
commit transaction

交易B

begin transaction
    update Orders set OrderId=14
    waitfor delay '00:00:5'; -- waits for 5 second
    update Customers set LastName = 'EbneSina'
commit transaction

如果两个事务同时执行,事务 A 锁定并更新 Customers 表,而事务 B 锁定并更新订单表。延迟5秒后,交易 A 会查找订单表的锁定,该表已由交易 B 和交易 B持有 Customers 表中查找已由事务 A 保留的锁定。因此,两个事务都无法继续进行,发生死锁。 我的问题是,当发生死锁时,两个事务中的哪一个将被中止。 首先,我执行交易 A 然后执行交易B,sql server中止交易 A 然后首先执行交易 B 然后 A 结果相同,事务A再次被排除。它困惑了我! 谢谢你的帮助。

2 个答案:

答案 0 :(得分:2)

您可以在SET DEADLOCK_PRIORITY (Transact-SQL)中了解条件:

  

选择哪个会话作为死锁受害者取决于每个会话   会话的死锁优先级:

     
      
  • 如果两个会话具有相同的死锁优先级,则SQL Server实例会选择回滚成本较低的会话   死锁的受害者。例如,如果两个会话都设置了它们   死锁优先级为HIGH,实例将选择作为受害者   它估计的会话回滚成本较低。

  •   
  • 如果会话具有不同的死锁优先级,则选择具有最低死锁优先级的会话作为死锁牺牲品。

  •   

对于您的情况,DBMS应该将 A 视为要回滚的较便宜的事务。

答案 1 :(得分:0)

没有办法知道只是查看查询。基本上,就我理解的事情而言,引擎会考虑死锁中涉及的所有事务,并尝试确定哪一个将成为最糟糕的"回滚。

因此,如果您的Customers表中有2行,Orders表中有9000000行,那么回滚UPDATE应用于{ {1}}比应用于Customers的那个。