现在的位置: 首页 > 综合 > 正文

增加Index来解决Deadlock的案例

2013年05月04日 ⁄ 综合 ⁄ 共 551字 ⁄ 字号 评论关闭

 

  最近在解决一个数据库死锁的问题,按说数据库死锁依靠强大的数据库自身的探查功能很容易找到发生位置从而进行分析解决。 但是最近遇到一个很奇怪的死锁案例,通过 –T 1222的switch,获得了死锁发生时候的SQL调用代码,和死锁资源情况发现造成死锁的双方都宣称获得了同一个资源的X锁,并且还要请求U锁,最终相互等待。经过一番探索发现这个等待的资源是表上的Cluster Index。 双方都获得了不同page上的x锁,而请求其他page上的U锁,而不是table级别的,所以在SQLServer,我就误以为两个session在等待同一个资源。

  最终的原因是,一个Update语句之后的where子句没有用任何index的字段进行检索,这样SQLServer就进行table scan检索所有数据以找到符合要求的row,方法就是在目标行上加U锁,然后检查是否需要更新,如果需要就升级成X锁,否则释放U锁,看下图。这样低效的操作遇到大的并发执行时候很容易相互死锁,这样问题就发生了。

 

image

 

解决办法嘛,就是改写where子句,或者建立index以保证所有查询的column都有index这样,sqlserver就不会进行table scan而是进行index的查询然后直接定位需要更新的目标行,U锁-〉X锁-〉释放X锁。

 

image

抱歉!评论已关闭.