且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

数据库死锁问题 及 解决方法 <收藏>

更新时间:2022-08-14 21:17:18

什么是数据库死锁

     每个使用关系型数据库的程序都可能遇到数据死锁的情况。理解什么是死锁之前先要了解锁定的概念:如果需要“修改”一条数据,首先数据库管理系统会在上面加锁,以保证在同一时间只有一个事务能进行修改操作。锁定(Locking)发生在当一个事务获得对某一资源的“锁”时,这时,其他的事务就不能更改这个资源了,这种机制的存在是为了保证数据一致性。

     多数情况下,可以认为如果一个资源被锁定,它总会在以后某个时间被释放。而死锁发生在当多个进程访问同一数据库时,其中每个进程拥有的锁都是其他进程所需的,由此造成每个进程都无法继续下去。简单的说,进程A等待进程B释放他的资源,B又等待A释放他的资源,这样就互相等待就形成死锁。

  • 导致数据库死锁的原因

     一般情况只发生锁超时,就是一个进程需要访问数据库表或者字段的时候,另外一个程序正在执行带锁的访问(比如修改数据),那么这个进程就会等待,当等了很久锁还没有解除的话就会锁超时,报告一个系统错误,拒绝执行相应的SQL操作。

     发生死锁的情况比较少,比如一个进程需要访问两个资源(数据库表或者字段),当获取一个资源的时候进程就对它执行锁定,然后等待下一个资源空闲,这时候如果另外一个进程也需要两个资源,而已经获得并锁定了第二个资源,那么就会死锁,因为当前进程锁定第一个资源等待第二个资源,而另外一个进程锁定了第二个资源等待第一个资源,两个进程都永远得不到满足。

  • 数据库死锁的解决方案

 

use master        --必须在master数据库中创建
 2数据库死锁问题 及 解决方法 <收藏>go
 3数据库死锁问题 及 解决方法 <收藏>
 4数据库死锁问题 及 解决方法 <收藏>if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[p_lockinfo]'and OBJECTPROPERTY(id, N'IsProcedure'= 1)
 5数据库死锁问题 及 解决方法 <收藏>drop procedure [dbo].[p_lockinfo]
 6数据库死锁问题 及 解决方法 <收藏>GO
 7数据库死锁问题 及 解决方法 <收藏>
 8数据库死锁问题 及 解决方法 <收藏>/*--处理死锁
 9数据库死锁问题 及 解决方法 <收藏>
10数据库死锁问题 及 解决方法 <收藏>        查看当前进程,或死锁进程,并能自动杀掉死进程
11数据库死锁问题 及 解决方法 <收藏>
12数据库死锁问题 及 解决方法 <收藏>        因为是针对死锁的,所以如果有死锁进程,只能查看死锁进程
13数据库死锁问题 及 解决方法 <收藏>        当然,你可以通过参数控制,不管有没有死锁,都只查看死锁进程
14数据库死锁问题 及 解决方法 <收藏>
15数据库死锁问题 及 解决方法 <收藏>        感谢: caiyunxia,jiangopen 两位提供的参考信息
16数据库死锁问题 及 解决方法 <收藏>
17数据库死锁问题 及 解决方法 <收藏>--邹建 2004.04(引用请保留此信息)--*/

18数据库死锁问题 及 解决方法 <收藏>
19数据库死锁问题 及 解决方法 <收藏>/*--调用示例
20数据库死锁问题 及 解决方法 <收藏>
21数据库死锁问题 及 解决方法 <收藏>        exec p_lockinfo
22数据库死锁问题 及 解决方法 <收藏>--*/

23数据库死锁问题 及 解决方法 <收藏>create proc p_lockinfo
24数据库死锁问题 及 解决方法 <收藏>@kill_lock_spid bit=1,                --是否杀掉死锁的进程,1 杀掉, 0 仅显示
25数据库死锁问题 及 解决方法 <收藏>@show_spid_if_nolock bit=1        --如果没有死锁的进程,是否显示正常进程信息,1 显示,0 不显示
26数据库死锁问题 及 解决方法 <收藏>as
27数据库死锁问题 及 解决方法 <收藏>set nocount on
28数据库死锁问题 及 解决方法 <收藏>declare @count int,@s nvarchar(1000),@i int
29数据库死锁问题 及 解决方法 <收藏>select id=identity(int,1,1),标志,
30数据库死锁问题 及 解决方法 <收藏>        进程ID=spid,线程ID=kpid,块进程ID=blocked,数据库ID=dbid,
31数据库死锁问题 及 解决方法 <收藏>        数据库名=db_name(dbid),用户ID=uid,用户名=loginame,累计CPU时间=cpu,
32数据库死锁问题 及 解决方法 <收藏>        登陆时间=login_time,打开事务数=open_tran,        进程状态=status,
33数据库死锁问题 及 解决方法 <收藏>        工作站名=hostname,应用程序名=program_name,工作站进程ID=hostprocess,
34数据库死锁问题 及 解决方法 <收藏>        域名=nt_domain,网卡地址=net_address
35数据库死锁问题 及 解决方法 <收藏>into #t from(
36数据库死锁问题 及 解决方法 <收藏>        select 标志='死锁的进程',
37数据库死锁问题 及 解决方法 <收藏>                spid,kpid,a.blocked,dbid,uid,loginame,cpu,login_time,open_tran,
38数据库死锁问题 及 解决方法 <收藏>                status,hostname,program_name,hostprocess,nt_domain,net_address,
39数据库死锁问题 及 解决方法 <收藏>                s1=a.spid,s2=0
40数据库死锁问题 及 解决方法 <收藏>        from master..sysprocesses a join (
41数据库死锁问题 及 解决方法 <收藏>                select blocked from master..sysprocesses group by blocked
42数据库死锁问题 及 解决方法 <收藏>                )b on a.spid=b.blocked where a.blocked=0
43数据库死锁问题 及 解决方法 <收藏>        union all
44数据库死锁问题 及 解决方法 <收藏>        select '|_牺牲品_>',
45数据库死锁问题 及 解决方法 <收藏>                spid,kpid,blocked,dbid,uid,loginame,cpu,login_time,open_tran,
46数据库死锁问题 及 解决方法 <收藏>                status,hostname,program_name,hostprocess,nt_domain,net_address,
47数据库死锁问题 及 解决方法 <收藏>                s1=blocked,s2=1
48数据库死锁问题 及 解决方法 <收藏>        from master..sysprocesses a where blocked<>0
49数据库死锁问题 及 解决方法 <收藏>)a order by s1,s2
50数据库死锁问题 及 解决方法 <收藏>
51数据库死锁问题 及 解决方法 <收藏>select @count=@@rowcount,@i=1
52数据库死锁问题 及 解决方法 <收藏>
53数据库死锁问题 及 解决方法 <收藏>if @count=0 and @show_spid_if_nolock=1
54数据库死锁问题 及 解决方法 <收藏>begin
55数据库死锁问题 及 解决方法 <收藏>        insert #t
56数据库死锁问题 及 解决方法 <收藏>        select 标志='正常的进程',
57数据库死锁问题 及 解决方法 <收藏>                spid,kpid,blocked,dbid,db_name(dbid),uid,loginame,cpu,login_time,
58数据库死锁问题 及 解决方法 <收藏>                open_tran,status,hostname,program_name,hostprocess,nt_domain,net_address
59数据库死锁问题 及 解决方法 <收藏>        from master..sysprocesses
60数据库死锁问题 及 解决方法 <收藏>        set @count=@@rowcount
61数据库死锁问题 及 解决方法 <收藏>end
62数据库死锁问题 及 解决方法 <收藏>
63数据库死锁问题 及 解决方法 <收藏>if @count>0
64数据库死锁问题 及 解决方法 <收藏>begin
65数据库死锁问题 及 解决方法 <收藏>        create table #t1(id int identity(1,1),a nvarchar(30),b Int,EventInfo nvarchar(255))
66数据库死锁问题 及 解决方法 <收藏>        if @kill_lock_spid=1
67数据库死锁问题 及 解决方法 <收藏>        begin
68数据库死锁问题 及 解决方法 <收藏>                declare @spid varchar(10),@标志 varchar(10)
69数据库死锁问题 及 解决方法 <收藏>                while @i<=@count
70数据库死锁问题 及 解决方法 <收藏>                begin
71数据库死锁问题 及 解决方法 <收藏>                        select @spid=进程ID,@标志=标志 from #t where id=@i
72数据库死锁问题 及 解决方法 <收藏>                        insert #t1 exec('dbcc inputbuffer('+@spid+')')
73数据库死锁问题 及 解决方法 <收藏>                        if @@rowcount=0 insert #t1(a) values(null)
74数据库死锁问题 及 解决方法 <收藏>                        if @标志='死锁的进程' exec('kill '+@spid)
75数据库死锁问题 及 解决方法 <收藏>                        set @i=@i+1
76数据库死锁问题 及 解决方法 <收藏>                end
77数据库死锁问题 及 解决方法 <收藏>        end
78数据库死锁问题 及 解决方法 <收藏>        else
79数据库死锁问题 及 解决方法 <收藏>                while @i<=@count
80数据库死锁问题 及 解决方法 <收藏>                begin
81数据库死锁问题 及 解决方法 <收藏>                        select @s='dbcc inputbuffer('+cast(进程ID as varchar)+')' from #t where id=@i
82数据库死锁问题 及 解决方法 <收藏>                        insert #t1 exec(@s)
83数据库死锁问题 及 解决方法 <收藏>                        if @@rowcount=0 insert #t1(a) values(null)
84数据库死锁问题 及 解决方法 <收藏>                        set @i=@i+1
85数据库死锁问题 及 解决方法 <收藏>                end
86数据库死锁问题 及 解决方法 <收藏>        select a.*,进程的SQL语句=b.EventInfo
87数据库死锁问题 及 解决方法 <收藏>        from #t a join #t1 b on a.id=b.id
88数据库死锁问题 及 解决方法 <收藏>        order by 进程ID
89数据库死锁问题 及 解决方法 <收藏>end
90数据库死锁问题 及 解决方法 <收藏>set nocount off

91数据库死锁问题 及 解决方法 <收藏>go



本文转自温景良(Jason)博客园博客,原文链接:http://www.cnblogs.com/wenjl520/archive/2009/07/04/1517003.html,如需转载请自行联系原作者