MSSQL死锁产生原因及解决方法
作者:网络转载 发布时间:[ 2016/5/24 15:41:00 ] 推荐标签:数据库 死锁
在该案例中process65db88, process1d0045948为语句1的进程,process629dc8 为语句2的进程; 语句2获取了1689766页上的更新锁,在等待1686247页上的更新锁;而语句1则获取了1686247页上的更新锁在等待1689766页上的更新锁,两个语句等待的资源形成了一个环路,造成死锁。
5) 如何解决死锁
针对如上死锁案例,分析其对应语句执行计划如下:

通过执行计划可以看出,在查找需要更新的数据时使用的是索引扫描,比较耗费性能,这样造成锁定资源时间过长,增加了语句并发执行时产生死锁的概率。
处理方式:
1. 在表上建立一个聚集索引。
2. 对语句更新的相关字段建立包含索引。
优化后该语句执行计划如下:

优化后的执行计划使用了索引查找,将大幅提升该查询语句的性能,降低了锁定资源的时间,同时也减少了锁定资源的范围,这样降低了锁资源循环等待事件发生的概率,对于预防死锁的发生会有一定的作用。
死锁是无法完全避免的,但如果应用程序适当处理死锁,对涉及的任何用户及系统其余部分的影响可降至低(适当处理是指发生错误1205时,应用程序重新提交批处理,第二次尝试大多能成功。一个进程被杀死,它的事务被取消,它的锁被释放,死锁中涉及到的另一个进程可以完成它的工作并释放锁,所以不具备产生另一个死锁的条件了。)
四、 如何预防死锁
阻止死锁的途径是避免满足死锁条件的情况发生,为此我们在开发的过程中需要遵循如下原则:
尽量避免并发的执行涉及到修改数据的语句。 要求每一个事务一次将所有要使用到的数据全部加锁,否则不允许执行。 预先规定一个加锁顺序,所有的事务都必须按照这个顺序对数据执行封锁。如不同的过程在事务内部对对象的更新执行顺序应尽量保证一致。 每个事务的执行时间不可太长,对程序段的事务可考虑将其分割为几个事务。在事务中不要求输入,应该在事务之前得到输入,然后快速执行事务。 使用尽可能低的隔离级别。 数据存储空间离散法。该方法是指采用各种手段,将逻辑上在一个表中的数据分散的若干离散的空间上去,以便改善对表的访问性能。主要通过将大表按行或者列分解为若干小表,或者按照不同的用户群两种方法实现。 编写应用程序,让进程持有锁的时间尽可能短,这样其它进程不必花太长的时间等待锁被释放。

sales@spasvo.com