同事的程序中,经常发生的情况是:在程序运行过程中,突然无缘无故的停住了,没有在继续运行下去。后来经过调试发现是因为 数据库 发生了死锁。对于 数据库 的死锁,不是很明白,google了下,查到一些资料。 地址:http://www.cnblogs.com/xzq686/archive/20
同事的程序中,经常发生的情况是:在程序运行过程中,突然无缘无故的停住了,没有在继续运行下去。后来经过调试发现是因为数据库发生了死锁。对于数据库的死锁,不是很明白,google了下,查到一些资料。
地址:http://www.cnblogs.com/xzq686/archive/2008/04/24/1168784.html
表现一:
一个用户a 访问表a(锁住了表a),然后又访问表b
另一个用户b 访问表b(锁住了表b),然后企图访问表a
这时用户a由于用户b已经锁住表b,它必须等待用户b释放表b,才能继续,好了他老人家就只好老老实实在这等了
同样用户b要等用户a释放表a才能继续这就死锁了
解决方法:
这种死锁是由于你的程序的bug产生的,除了调整你的程序的逻辑别无他法
仔细分析你程序的逻辑,
1:尽量避免同时锁定两个资源
2: 必须同时锁定两个资源时,要保证在任何时刻都应该按照相同的顺序来锁定资源.
表现二:
用户a读一条纪录,然后修改该条纪录
这是用户b修改该条纪录
这里用户a的事务里锁的性质由共享锁企图上升到独占锁(for update),而用户b里的独占锁由于a有共享锁存在所以必须等a释
放掉共享锁,而a由于b的独占锁而无法上升的独占锁也就不可能释放共享锁,于是出现了死锁。
这种死锁比较隐蔽,但其实在稍大点的项目中经常发生。
解决方法:
让用户a的事务(即先读后写类型的操作),在select 时就是用update lock
语法如下:
select * from table1 with(updlock) where ....
如果真的table被锁住了,可以通过下面的方法来解锁:
sql server企业管理器->对应的数据库->管理->当前活动->锁/进程id
将对应的被锁住的进程关闭。
还有一种方法,就是在你不知道究竟是哪张表被锁,由何种原因被锁,可以重新启动数据库来解决,但不保证下次又被锁住,因为还没有找到问题的根本原因。
要避免锁表,在操作数据库最好不要用独占方式。