sql server 2000阻塞和死锁问题的查看与解决方法(转)

在实际引用当中,数据库阻塞和死锁在程序开发过程经常出现,下面通过介绍数据库阻塞和数据库死锁,并提供查看和解决阻塞和死锁的方法
https://www.jb51.net/article/45473.htm

数据库发生阻塞和死锁的现象:

一、数据库阻塞的现象:第一个连接占有资源没有释放,而第二个连接需要获取这个资源。如果第一个连接没有提交或者回滚,第二个连接会一直等待下去,直到第一个连接释放该资源为止。对于阻塞,数据库无法处理,所以对数据库操作要及时地提交或者回滚。
二、数据库死锁的现象:第一个连接占有资源没有释放,准备获取第二个连接所占用的资源,而第二个连接占有资源没有释放,准备获取第一个连接所占用的资源。这种互相占有对方需要获取的资源的现象叫做死锁。对于死锁,数据库处理方法:牺牲一个连接,保证另外一个连接成功执行。

例如,一个客户端应用程序线程有两个开放式连接。该线程异步启动事务并在第一个连接上发出查询。应用程序随后启动其它事务,在另一个连接上发出查询并等待结果。当 SQL   Server   返回其中一个连接的结果时,应用程序开始处理这些结果。应用程序就这样处理结果,直到生成结果的查询被另一个连接上执行的查询阻塞而导致再没有可用的结果为止。此时第一个连接阻塞,无限期等待处理更多的结果。第二个连接没有在锁上阻塞,但仍试图将结果返回给应用程序。然而,由于应用程序阻塞而在第一个连接上等待结果,第二个连接的结果将得不到处理。  

下面是查看并处理sql server 2000阻塞和死锁的方法:

USE [master]
--p_lockinfo
GO
/****** Object:  StoredProcedure [dbo].[p_lockinfo]    Script Date: 07/03/2019 09:08:17 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
/* 
在SQL Query Analyzer 如何执行:  
exec master.dbo.p_lockinfo 0,0  ---显示死锁的进程,不显示正常的进程 
exec master.dbo.p_lockinfo 1,0  ---杀死死锁的进程,不显示正常的进程 
*/
 
/* 在master数据库中建立如下的procedure,并赋予某些用户执行权限 */
ALTER proc  [dbo].[p_lockinfo] 
    @kill_lock_spid bit=0,        --是否杀掉死锁的进程,1 杀掉, 0 仅显示 
    @show_spid_if_nolock bit=1    --如果没有死锁的进程,是否显示正常进程信息,1 显示,0 不显示 
as
    declare @count int,@s nvarchar(4000),@i int 
    select id=identity(int,1,1),标志, 
        进程ID=spid,线程ID=kpid,块进程ID=blocked,数据库ID=dbid, 
        数据库名=db_name(dbid),用户ID=uid,用户名=loginame,累计CPU时间=cpu, 
        登陆时间=login_time,打开事务数=open_tran, 进程状态=status, 
        工作站名=hostname,应用程序名=program_name,工作站进程ID=hostprocess, 
        域名=nt_domain,网卡地址=net_address 
    into #t from( 
        select 标志='死锁的进程', 
            spid,kpid,a.blocked,dbid,uid,loginame,cpu,login_time,open_tran, 
            status,hostname,program_name,hostprocess,nt_domain,net_address, 
            s1=a.spid,s2=0 
        from master..sysprocesses a join ( 
        select blocked from master..sysprocesses group by blocked 
        )b on a.spid=b.blocked where a.blocked=0 
     union all 
     select '|_牺牲品_>', 
        spid,kpid,blocked,dbid,uid,loginame,cpu,login_time,open_tran, 
        status,hostname,program_name,hostprocess,nt_domain,net_address, 
        s1=blocked,s2=1 
     from master..sysprocesses a where blocked<>0 
    )a order by s1,s2
     
    select @count=@@rowcount,@i=1
    if @count=0 and @show_spid_if_nolock=1 
    begin 
        insert #t 
        select 标志='正常的进程', 
            spid,kpid,blocked,dbid,db_name(dbid),uid,loginame,cpu,login_time, 
            open_tran,status,hostname,program_name,hostprocess,nt_domain,net_address 
        from master..sysprocesses 
        set @count=@@rowcount 
    end 
     
    if @count>0 
    begin 
        create table #t1(id int identity(1,1),a nvarchar(30),b Int,EventInfo nvarchar(3255)) 
        if @kill_lock_spid=1 
        begin 
            declare @spid varchar(10),@标志 varchar(10) 
            while @i<=@count 
            begin 
                select @spid=进程ID,@标志=标志 from #t where id=@i 
                insert #t1 exec('dbcc inputbuffer('+@spid+')') 
                if @标志='死锁的进程' exec('kill'+@spid) 
                set @i=@i+1 
            end 
        end 
        else 
        while @i<=@count 
        begin 
           select @s='dbcc inputbuffer('+cast(进程ID as varchar(1250))+')' from #t where id=@i 
           insert #t1 exec(@s) 
           set @i=@i+1 
        end 
        select 进程的SQL语句=b.EventInfo ,a.*
        from #t a join #t1 b on a.id=b.id 
    end 

set nocount off

go

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值