服务器阻塞是个很头疼的问题,多少个日日夜夜,只因为服务器的呼唤,我一路狂奔就去医院杀“阻塞进程”去了。
搞完ISO15189,我想解决这个问题。
一、自动解锁。
使用Select @@LOCK_TIMEOUT命令可以看得到当前数据库加锁的超时期限,单位是毫秒。如果为“-1”,代表不会有超时,服务器将会一直处于加锁状态。
因此,我能想到的第一种方法就是”SET LOCK_TIMEOUT 30000″。既然服务器都给予了这样一个功能,那我不如直接用上。按照如上设定,如果加锁持续了30秒,则自动解锁!
想象很美好,但是现实很残酷,第二天,我还是跑过去杀进程去了!阻塞的进程压根就会一直存在!
二、自动结束阻塞进程
以下为结束阻塞进程的SQL存储过程:
--结束SQL阻塞的进程%%%%%%%%%%%%%%%%%%%%%%
create procedure sp_Kill_lockProcess
as
begin
SET NOCOUNT ON
declare @spid int,@bl int,
@intTransactionCountOnEntry int,
@intRowcount int,
@intCountProperties int,
@intCounter int,
@sSql nvarchar (200)
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
while @intCounter
begin
-- 取第一 www.111cn.net 条记录
select @spid = spid,@bl = bl
from #tmp_lock_who where Id = @intCounter
begin
if @spid =0
begin
set @sSql="kill " + CAST(@bl AS VARCHAR(10))
exec sp_executesql @sSql
end
end
-- 循环指针下移
set @intCounter = @intCounter + 1
end
drop table #tmp_lock_who
SET NOCOUNT OFF
return 0
end
go
将上述语句执行后,在master数据库下,即可以找到存储过程sp_Kill_lockProcess。
在SQL SERVER代理中添加作业KillBlocking,将执行时间设置为每10分钟一次,搞定!
测试一下,每天可以杀死三个阻塞进程,我们的LIS数据库啊,真烂。
如果你想进一步追踪阻塞的原因的话,把输出写入到日志中去就行了!
http://m.bbyears.com/jsp/52063.html
推荐访问:lis系统是什么 lis是什么意思