如何减少SQL Server死锁发生的情况
2008-08-30 09:57:06 来源:WEB开发网死锁是指在某组资源中,两个或两个以上的线程在执行过程中,在争夺某一资源时而造成互相等待的现象,若无外力的作用下,它们都将无法推进下去,死时就可能会产生死锁,这些永远在互相等待的进程称为死锁线程。简单的说,进程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来确定可能是哪些用户阻塞了其他用户,我们还可以用下面的存储过程来跟踪具体的死锁执行的影响:
create procedure sp_who_lock
as
begin
declare @spid int,@bl int,
@intTransactionCountOnEntry int,
@intRowcount int,
@intCountProperties int,
@intCounter int
create table #tmp_lock_who (id int identity(1,1),spid smallint,bl smallint)
IF @@ERROR<>0 RETURN @@ERROR
insert into #tmp_lock_who(spid,bl) select 0 ,blocked
from (select * from sysprocesses where blocked>0 ) a
where not exists(select * from (select * from sysprocesses where blocked>0 ) b
where a.blocked=spid)
union select spid,blocked from sysprocesses where blocked>0
IF @@ERROR<>0 RETURN @@ERROR
-- 找到临时表的记录数
select @intCountProperties = Count(*),@intCounter = 1
from #tmp_lock_who
IF @@ERROR<>0 RETURN @@ERROR
if @intCountProperties=0
select '现在没有阻塞和死锁信息' as message
-- 循环开始
while @intCounter <= @intCountProperties
begin
-- 取第一条记录
select @spid = spid,@bl = bl
from #tmp_lock_who where id = @intCounter
begin
if @spid =0
select '引起数据库死锁的是: '+ CAST(@bl AS VARCHAR(10)) + '进程号,其执行的SQL语法如下'
else
select '进程号SPID:'+ CAST(@spid AS VARCHAR(10))+ '被' + '进程号SPID:'+ CAST(@bl AS VARCHAR(10)) +'阻塞,其当前进程执行的SQL语法如下'
DBCC INPUTBUFFER (@bl )
end
-- 循环指针下移
set @intCounter = @intCounter + 1
end
drop table #tmp_lock_who
return 0
end
我们只需要通过在查询分析器里面执行sp_who_lock,就可以具体捕捉到执行的堵塞进程,这时我们就可以对对应的SQL语句或者存储过程进行性能上面的改进及设计。
- ››如何检查oracle的归档空间是否满了
- ››如何在浏览器中打开PDF文件并实现预览的思路与代码...
- ››如何改Win7系统我的文档保存位置
- ››SQL Server 2008 R2 下如何清理数据库日志文件
- ››如何让ios app支持32位和64位
- ››如何删除Windows 8系统未知的账户
- ››如何提高win7系统的响应速度?
- ››sqlite 存取中文的解决方法
- ››SQL2005、2008、2000 清空删除日志
- ››如何避免iPhone应用中内存泄露
- ››如何转移Win 7系统C盘的用户文件夹
- ››SQL Server 2005和SQL Server 2000数据的相互导入...
更多精彩
赞助商链接