You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

READ UNCOMMITTED隔离级别下SQL Server死锁原因排查

死锁问题排查:READ UNCOMMITTED隔离级别下仍出现死锁的原因

我收到错误提示:Transaction (Process ID 60) was deadlocked on lock resources with another process ...。我有如下两个简单查询:

Query 1

BEGIN try    
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
BEGIN tran  

    update RestaurantAccount set CreatedOn = GETDATE()
        where Id = 1
    
    WAITFOR DELAY '00:00:6'
    
    update RestaurantInvoice set CreatedOn = GETDATE()
        where Id = 1

commit tran    

END try    
BEGIN catch    

IF(@@TRANCOUNT > 0)    
rollback tran    

          SELECT  
             cast(1 as bit) as hasError
            ,ERROR_LINE() AS ErrorLine  
            ,(isnull(ERROR_MESSAGE(),'') + isnull(ERROR_PROCEDURE(),'')) AS ErrorMessage
END catch     

Query 2

BEGIN try    
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
BEGIN tran  

    update RestaurantInvoice set CreatedOn = GETDATE()
        where Id = 1
    
    WAITFOR DELAY '00:00:6'
    
    update RestaurantAccount set CreatedOn = GETDATE()
        where Id = 1

commit tran    

END try    
BEGIN catch    

IF(@@TRANCOUNT > 0)    
rollback tran    

         SELECT  
             cast(1 as bit) as hasError
            ,ERROR_LINE() AS ErrorLine  
            ,(isnull(ERROR_MESSAGE(),'')  ) AS ErrorMessage

END catch  

我为两个查询都设置了READ UNCOMMITTED事务隔离级别,先执行第一个查询后立即执行第二个,却仍出现死锁错误。我原以为READ UNCOMMITTED级别不会产生锁,请问该死锁产生的原因是什么?(我使用的是SQL Server 2014)


死锁产生的核心原因

READ UNCOMMITTED隔离级别仅影响读取操作的锁行为:它允许读取未提交的数据(脏读),读取时不会加共享锁,也不会阻塞排它锁。但修改操作(UPDATE/INSERT/DELETE)完全不受READ UNCOMMITTED的约束,SQL Server执行修改时依然会申请并持有排它锁(X锁),直到整个事务提交或回滚才会释放。

你的两个事务的执行流程完全命中了死锁的经典场景:

  1. 事务1先执行UPDATE RestaurantAccount WHERE Id=1,获取了RestaurantAccount表中Id=1行的排它锁
  2. 事务2几乎同时执行UPDATE RestaurantInvoice WHERE Id=1,获取了RestaurantInvoice表中Id=1行的排它锁
  3. 等待6秒后,事务1尝试修改RestaurantInvoice的Id=1行,但该行已被事务2持有排它锁,事务1进入等待状态
  4. 同时事务2尝试修改RestaurantAccount的Id=1行,该行已被事务1持有排它锁,事务2也进入等待状态
  5. 两个事务形成循环依赖,互相等待对方释放锁,触发SQL Server的死锁检测机制,最终其中一个事务会被强制终止以打破死锁

总结

  • READ UNCOMMITTED仅控制读取操作的锁策略,对修改操作的锁行为无任何影响
  • 本次死锁的本质是两个事务以相反的顺序获取资源锁,和读取隔离级别没有关系

内容的提问来源于stack exchange,提问作者Mohammad Galouz Lee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 00:32:39