没法得到数据库'model'上的排他锁 解决办法

 

今天在编写建库工具的时候遇到排他锁问题,数据库创建失败,从百度中看到了,想与你们分享.html

解决方法:sql

在查询分析器中运行以下代码便可:数据库

declare @sql varchar(100)
while 1=1
begin
select top 1 @sql = 'kill '+cast(spid as varchar(3))
from master..sysprocesses
where spid > 50 and spid <> @@spid
if @@rowcount = 0
break
exec(@sql)
end
服务器

死锁是指在某组资源中,两个或两个以上的线程在执行过程当中,在争夺某一资源时而形成互相等待的现象,若无外力的做用下,它们都将没法推动下去,死时就可能会产生死锁,这些永远在互相等待的进程称为死锁线程。简单的说,进程A等待进程B释放他的资源,B又等待A释放他的资源,这样互相等待就造成死锁。网络

如在数据库中,若是须要对一条数据进行修改,首先数据库管理系统会在上面加锁,以保证在同一时间只有一个事务能进行修改操做。如事务1的线程 T1具备表A上的排它锁,事务2的线程T2 具备表B上的排它锁,而且以后须要表A上的锁。事务2没法得到这一锁,由于事务1已拥有它。事务2被阻塞,等待事务1。而后,事务1须要表B的锁,但没法得到锁,由于事务2将它锁定了。事务在提交或回滚以前不能释放持有的锁。由于事务须要对方控制的锁才能继续操做,因此它们不能提交或回滚,这样数据库就会发生死锁了。并发

如在编写存储过程的时候,因为有些存储过程事务性的操做比较频繁,若是先锁住表A,再锁住表B,那么在全部的存储过程当中都要按照这个顺序来锁定它们。若是无心中某个存储过程当中先锁定表B,再锁定表A,这可能就会致使一个死锁。并且死锁通常是不太容易被发现的。数据库设计

若是服务器上常常出现这种死锁状况,就会下降服务器的性能,因此应用程序在使用的时候,咱们就须要对其进行跟踪,使用sp_who和sp_who2来肯定多是哪些用户阻塞了其余用户,咱们还能够用下面的存储过程来跟踪具体的死锁执行的影响工具

咱们只须要经过在查询分析器里面执行sp_who_lock,就能够具体捕捉到执行的堵塞进程,这时咱们就能够对对应的SQL语句或者存储过程进行性能上面的改进及设计。性能

因此咱们在数据库设计的时候,虽然不能彻底避免死锁,但可使死锁的数量尽可能减小。增长事务的吞吐量并减小系统开销,由于只有不多的事务,因此就得遵循下面的原则:线程

按同一顺序访问对象

若是全部并发事务按同一顺序访问对象,则发生死锁的可能性会下降。在写SQL语句或存储过程的时候,就须要按照顺序在两个并发事务中先得到表A上的锁,而后得到表B上的锁,当第一个事务完成以前,另外一个事务被阻塞在表A上。第一个事务提交或回滚后,第二个事务继续进行,而不能在语句里面写先得到表B上的锁,而后再得到表A的锁。

避免事务中的用户交互

避免编写包含用户交互的事务,由于运行没有用户交互的批处理的速度要远远快于用户手动响应查询的速度,例如答复应用程序请求参数的提示。例如,若是事务正在等待用户输入,而用户就去作别的事了,则用户将此事务挂起使之不能完成。这样将下降系统的吞吐量,由于事务持有的任何锁只有在事务提交或回滚时才会释放。即便不出现死锁的状况,访问同一资源的其它事务也会被阻塞,等待该事务完成。

保持事务简短并在一个批处理中

在同一数据库中并发执行多个须要长时间运行的事务时一般发生死锁。事务运行时间越长,其持有排它锁或更新锁的时间也就越长,从而堵塞了其它活动并可能致使死锁。保持事务在一个批处理中,能够最小化事务的网络通讯往返量,减小完成事务可能的延迟并释放锁。

使用低隔离级别

肯定事务是否能在更低的隔离级别上运行。执行提交读容许事务读取另外一个事务已读取(未修改)的数据,而没必要等待第一个事务完成。使用较低的隔离级别(例如提交读)而不使用较高的隔离级别(例如可串行读)能够缩短持有共享锁的时间,从而下降了锁定争夺。

使用绑定链接

使用绑定链接使同一应用程序所打开的两个或多个链接能够相互合做。次级链接所得到的任何锁能够象由主链接得到的锁那样持有,反之亦然,所以不会相互阻塞。

下面有一些对死锁发生的一些建议:

(1)对于频繁使用的表使用集簇化的索引;

(2)设法避免一次性影响大量记录的T-SQL语句,特别是INSERT和UPDATE语句;

(3)设法让UPDATE和DELETE语句使用索引;

(4)使用嵌套事务时,避免提交和回退冲突;

(5)对一些数据不须要及时读取更新值的表在写SQL的时候在表后台加上(nolock),如:Select * from tableA(nolock)

相关文章
相关标签/搜索