SQL2005中的事务与锁定(七)
作者 佚名技术
来源 数据库编程
浏览
发布时间 2012-03-22
转换死锁发生在不同进程在查询相同的数据后准备尝试更新刚才查询的数据时,这时大家都持相同数据的共享锁定并都准备升级为更新锁,但是都因为对方不释放共享锁定而无法获取更新锁定,这是死锁发生,我们称这个为转换死锁。好下面我们模拟一下conversion死锁。 (约定:运行查询一后在3S内运行查询二) 查询一: select @@spid –-53 set transaction isolation level repeatable read begin tran select * from ta waitfor delay ''00:00:03'' update ta set col = ''B'' where id = 1 exec sp_us_lockinfo -–结果见图conversion1 commit tran 查询二: select @@spid –-52 set transaction isolation level repeatable read begin tran select * from ta waitfor delay ''00:00:05'' exec sp_us_lockinfo --结果见图conversion2 update ta set col = ''B'' where id = 1 –-系统检测到死锁,抛出1205错误 commit tran 图conversion1: 图conversion2: 查询二死锁1205信息 : 消息1205,级别13,状态45,第7 行 事务(进程ID 52)与另一个进程被死锁在锁资源上,并且已被选作死锁牺牲品。请重新运行该事务。 应用级死锁及不明死锁:这类死锁有点特殊,除了绑定外我们可能通过动态管理视图或函数是无法侦测到锁定信息,显然锁管理器可能也无法干预它。我们所能看到可能是一个长期占用的资源锁定,而这种锁定潜在造成更多死锁发生。比如说同一个应用程序的多线程间、应用程序调用外部程序等如果最终再与数据库发生联系,那显然还是数据库两个进程间的死锁,如果与非数据库联系,那么这种依赖于其它程序的状态锁定只能是无限期的等待,除非人为干预SQLSERVER是干预不了的。 我们把SQLSERVER锁管理器无法侦测的死锁称不明死锁,这类死锁可以借助SSIS来模拟,比如我们要完成一项任务就是把未导出的数据通过SSIS生成文件,并把已经导出的数据做上标识。我们用一个过程模拟插入数据,并在事务提交前启动SSIS包完成数据导出并修改标识,这时我们如果想要在一个事务里完成所有工作那是不可能的,会造成事务一直运行,并且我们锁定管理器也无法侦测。 第五,锁管理器:在SQLSERVER中一有独立线程周期性的检查系统的死锁,当死锁发生时,死锁的检查周期缩小到毫秒级,直到死锁的频率降低再次恢复到默认的周期。如果侦测到锁定,管理器会权衡回滚的代价,并依据是否已经标识为回滚引起不明状态及牺牲品的优先级别选择牺牲品,杀掉进程并发送1205错误,这也就意思牺牲品所占的资源全部释放,这样其它相关的进程可以继续运行。 最后提一上我们先前提到的闩及自旋锁定,它们是预防死锁而不是解决死锁,这两种轻量级的锁定之所以能预防死锁是因为MS严谨的控制达到不需要管理死锁。 综上所述,死锁是无法完全避免的,对于SQLSERVER所能侦测的死锁还是比较容易处理的,恰当的做好出错后的处理使得对死锁相关的用户进程的影响降到最低。所谓的愉当就是接受到1205错误时应用程序应能够再次提交处理或提醒1205错误的用户进行相应处理。我们还可以做的一件事就是尽量回避死锁, 回避死锁可以从下面几点出发: l 事务尽可能的短,锁定时间就会短; l 应用程序做好死锁发生后处理; l |
凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢! |
你可能对下面的文章感兴趣
关于SQL2005中的事务与锁定(七)的所有评论