Sybase数据库死锁对策
如何处理数据库中的死锁问题(五)

在开发和运维数据库系统的过程中,经常会遇到死锁问题。
死锁是指两个或多个进程在执行过程中,互相请求对方所持有的资源,同时又拒绝释放自己持有的资源,导致彼此都无法继续执行的情况。
如何处理数据库中的死锁问题成为数据库管理员和开发人员必须重视的一个方面。
1. 死锁问题的原因分析死锁问题主要是由于并发访问数据库中的共享资源时,对资源先后次序的控制不当引起的。
当多个进程需要同时访问同一个资源时,通过资源锁机制来保证数据的一致性和完整性。
然而,如果没有良好的资源访问控制策略,就容易导致死锁问题的发生。
2. 死锁问题的识别为了解决死锁问题,首先需要能够识别出死锁的存在。
数据库系统通常会提供一些工具和机制来帮助识别死锁,如死锁检测器。
死锁检测器可以追踪资源的分配和请求情况,以及进程的等待关系,并根据这些信息判断是否存在死锁。
3. 死锁问题的解决方法一旦识别出死锁问题的存在,就需要采取相应的解决方法来消除死锁。
以下是一些常用的死锁解决方法:a. 死锁超时机制死锁超时机制是一种简单但有效的解决方法。
当进程在一定时间内无法获得所需资源时,可以通过设置超时时间来主动放弃并重新尝试获取资源,以避免长时间的无谓等待。
b. 死锁检测与恢复死锁检测与恢复是一种较为复杂但比较全面的解决方法。
通过定期或实时地检测死锁的存在,然后采取相应的恢复策略。
常见的恢复策略有终止进程、回滚事务等。
c. 死锁预防死锁预防是一种在设计数据库系统时就考虑和解决死锁问题的方法。
通过合理的资源分配策略、避免不必要的资源竞争等手段来预防死锁的发生。
d. 死锁避免死锁避免是基于资源请求的动态分配的原则,根据当前系统状态和资源请求情况,通过预测资源请求的未来走向来避免潜在的死锁。
这需要对系统状态和资源请求进行动态调整和优化。
4. 其他注意事项处理数据库中的死锁问题还需要注意以下几个方面:a. 优化数据库设计合理的数据库设计在很大程度上可以减少死锁问题的发生。
通过合理的表和索引设计,可以降低并发事务对同一资源的竞争。
数据库的并发控制与死锁解决方案

数据库的并发控制与死锁解决方案随着科技的快速发展和互联网的普及,大量的数据被应用程序所处理和存储。
为了提高数据库的处理能力和运行效率,数据库系统引入了并发控制的技术。
并发控制是指在数据库系统中允许多个用户同时访问同一个数据库的能力,但同时又需要保证数据的一致性、完整性和准确性。
在并发控制的过程中,会出现一种称为死锁的情况。
死锁是指两个或多个事务互相等待对方释放所持有的资源,导致进程无法继续执行而进入死循环的状态。
死锁的出现会影响数据库系统的性能,并且会导致事务被阻塞无法完成。
为了解决并发控制和死锁的问题,数据库系统提供了以下几种解决方案:1. 锁机制:锁是并发控制中最常用的一种解决方案。
在数据库中,锁可以分为共享锁和排它锁。
共享锁允许多个事务读取同一资源,而排它锁则只允许一个事务对资源进行读写操作。
通过对资源施加合适的锁,可以保证数据库的数据一致性和完整性。
2. 事务隔离级别:数据库系统中提供了四个事务隔离级别,分别是读未提交、读已提交、可重复读和串行化。
选择合适的事务隔离级别可以避免一些并发带来的问题。
例如,在读未提交的隔离级别下,一个事务可以读取到其他事务尚未提交的数据,可能造成脏读的问题。
而在串行化的隔离级别下,每个事务都必须按照先后顺序依次执行,避免了并发带来的问题,但也牺牲了性能。
3. 死锁检测和死锁解除:数据库系统可以通过死锁检测来发现死锁的存在。
一旦发现死锁,系统可以采取多种方式来解除死锁。
常见的解除死锁的方法有回滚事务、终止阻塞的事务或者优化锁的分配策略。
通常情况下,数据库系统会根据一定的死锁检测算法来选择合适的死锁解除策略。
4. 优化数据库设计:合理的数据库设计也可以减少并发带来的问题。
例如,使用合适的索引和优化查询语句,可以减少数据库的锁冲突。
此外,可以将大表进行分区或分片存储,使得并发操作分散到多个节点上,减少锁冲突的可能性。
总之,数据库的并发控制和死锁解决方案是一个复杂且关键的问题。
造成数据库表死锁的原因分析及解决方案

造成数据库表死锁的原因分析及解决⽅案在联机事务处理(OLTP)的数据库应⽤系统中,多⽤户、多任务的并发性是系统最重要的技术指标之⼀。
为了提⾼并发性,⽬前⼤部分RDBMS都采⽤加锁技术。
然⽽由于现实环境的复杂性,使⽤加锁技术⼜不可避免地产⽣了死锁问题。
因此如何合理有效地使⽤加锁技术,最⼩化死锁是开发联机事务处理系统的关键。
⼀、死锁产⽣的原因在联机事务处理系统中,造成死机主要有两⽅⾯原因。
⼀⽅⾯,由于多⽤户、多任务的并发性和事务的完整性要求,当多个事务处理对多个资源同时访问时,若双⽅已锁定⼀部分资源但也都需要对⽅已锁定的资源时,⽆法在有限的时间内完全获得所需的资源,就会处于⽆限的等待状态,从⽽造成其对资源需求的死锁。
另⼀⽅⾯,数据库本⾝加锁机制的实现⽅法不同,各数据库系统也会产⽣其特殊的死锁情况。
如在Sybase SQL Server 11中,最⼩锁为2K⼀页的加锁⽅法,⽽⾮⾏级锁。
如果某张表的记录数少且记录的长度较短(即记录密度⾼,如应⽤系统中的系统配置表或系统参数表就属于此类表),被访问的频率⾼,就容易在该页上产⽣死锁。
⼆、容易发⽣死锁的⼏种情况如下:1、不同的存储过程、触发器、动态SQL语句段按照不同的顺序同时访问多张表;2、在交换期间添加记录频繁的表,但在该表上使⽤了⾮群集索引(non-clustered);3、表中的记录少,且单条记录较短,被访问的频率较⾼;4、整张表被访问的频率⾼(如代码对照表的查询等)。
三、以上死锁情况的对应解决⽅案1、在系统实现时应规定所有存储过程、触发器、动态SQL语句段中,对多张表的操作总是使⽤同⼀顺序。
如:有两个存储过程proc1、proc2,都需要访问三张表zltab、z2tab和z3tab,如果proc1按照zltab、z2tab和z3tab的顺序进⾏访问,那么,proc2也应该按照以上顺序访问这三张表。
2、对在交换期间添加记录频繁的表,使⽤群集索引(clustered),以减少多个⽤户添加记录到该表的最后⼀页上,在表尾产⽣热点,造成死锁。
引发Sybase数据库死锁的常见误区

图 1 两 个 串行 化 事 务
的 误 区 来 自技 术 层 面 。 事 实 上 技 术 层 面 出现 死 锁 一 般 是 设 计 不 当 造 成 的 。
2 误 区二 :处理顺 序相同不会产 生死锁 .
第 一 个 认 知 误 区 比 较 容 易 理 解 ,业 务 处 理 顺 序 发 生 冲
串行 化 事 务 是 保 障 事 务 完 整 性 的 必 要 条 件 .但 它 并 不 能 防 止 死 锁 ,比 如 图 1 示 的 两个 事 务 。 所
虽然 事务A和事务B 都是 串行化处 理事务 .但 由于 二者 锁定 临界资源 顺序 发生冲 突 .从而 形成死 锁链 ,这种情 况
然后分别开启两个事务 ,它们的执行顺序如图2 所示。 显然事务 A和事务B 的业务 处理顺序 一样 ,但是 照样会 出现死 锁 ,其 原 因在于 它们 的逻辑 处理 顺序相 互冲 突 这
不 了新 记 录 。 具体 步骤 如 图 3 示 。 所
可 以看 出 ,采 用 下 一 键 锁 机 制 可 以 避 免 出现 幻 读 ,但 是 ,事 务 A和 事 务 B 可 能 不 总 是 按 照 上 面 描 述 的 过 程 执 行 .事 务 A和 事 务 B 全 可 能 会 同 时 执 行 完 各 自第 二 步 完 图2 处 理 顺 序 相 同 的 两 事 务 执 行 顺 序 中 的 aJ步 .接 着 事 务 A执 行 bJ步 时 将 会 / \ / \ 出现 这 种 可 能 :事 务 A 求 共 享 锁 定 事 务 B 要 样 的逻 辑 死 锁 只 能 从 设 计 角度 上加 以修 改 。 插 入 记 录 所 属 的 数 据 页 .而 事 务 B 求 下 一 键 锁 .从 而 发 生 要
在 引发死 锁的认 知层面 上 目前有许 多常见 的错误 认 识 。有的是 非技术 层面 的 ,比如认 为程序 设计不 必对 死锁
数据库死锁问题及解决方法

数据库死锁问题及解决⽅法什么是数据库死锁每个使⽤关系型数据库的程序都可能遇到数据死锁的情况。
理解什么是死锁之前先要了解锁定的概念:如果需要“修改”⼀条数据,⾸先数据库管理系统会在上⾯加锁,以保证在同⼀时间只有⼀个事务能进⾏修改操作。
锁定(Locking)发⽣在当⼀个事务获得对某⼀资源的“锁”时,这时,其他的事务就不能更改这个资源了,这种机制的存在是为了保证数据⼀致性。
多数情况下,可以认为如果⼀个资源被锁定,它总会在以后某个时间被释放。
⽽死锁发⽣在当多个进程访问同⼀数据库时,其中每个进程拥有的锁都是其他进程所需的,由此造成每个进程都⽆法继续下去。
简单的说,进程A等待进程B释放他的资源,B⼜等待A释放他的资源,这样就互相等待就形成死锁。
导致数据库死锁的原因⼀般情况只发⽣锁超时,就是⼀个进程需要访问数据库表或者字段的时候,另外⼀个程序正在执⾏带锁的访问(⽐如修改数据),那么这个进程就会等待,当等了很久锁还没有解除的话就会锁超时,报告⼀个系统错误,拒绝执⾏相应的SQL操作。
发⽣死锁的情况⽐较少,⽐如⼀个进程需要访问两个资源(数据库表或者字段),当获取⼀个资源的时候进程就对它执⾏锁定,然后等待下⼀个资源空闲,这时候如果另外⼀个进程也需要两个资源,⽽已经获得并锁定了第⼆个资源,那么就会死锁,因为当前进程锁定第⼀个资源等待第⼆个资源,⽽另外⼀个进程锁定了第⼆个资源等待第⼀个资源,两个进程都永远得不到满⾜。
数据库死锁的解决⽅案use master --必须在master数据库中创建2go34if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[p_lockinfo]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)5drop procedure [dbo].[p_lockinfo]6GO78/**//*--处理死锁910 查看当前进程,或死锁进程,并能⾃动杀掉死进程1112 因为是针对死锁的,所以如果有死锁进程,只能查看死锁进程13 当然,你可以通过参数控制,不管有没有死锁,都只查看死锁进程1415 感谢: caiyunxia,jiangopen 两位提供的参考信息1617--邹建 2004.04(引⽤请保留此信息)--*/1819/**//*--调⽤⽰例2021 exec p_lockinfo22--*/23create proc p_lockinfo24@kill_lock_spid bit=1, --是否杀掉死锁的进程,1 杀掉, 0 仅显⽰25@show_spid_if_nolock bit=1 --如果没有死锁的进程,是否显⽰正常进程信息,1 显⽰,0 不显⽰26as27set nocount on28declare @count int,@s nvarchar(1000),@i int29selectid=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_address35into #t from(36 select 标志='死锁的进程',37spid,kpid,a.blocked,dbid,uid,loginame,cpu,login_time,open_tran,38status,hostname,program_name,hostprocess,nt_domain,net_address,39 s1=a.spid,s2=040 from master..sysprocesses a join (41 select blocked from master..sysprocesses group by blocked42 )b on a.spid=b.blocked where a.blocked=043 union all44 select '|_牺牲品_>',45 spid,kpid,blocked,dbid,uid,loginame,cpu,login_time,open_tran,46status,hostname,program_name,hostprocess,nt_domain,net_address,47 s1=blocked,s2=148 from master..sysprocesses a where blocked<>049)a order by s1,s25051select@count=@@rowcount,@i=15253if @count=0 and @show_spid_if_nolock=154begin55 insert #t56 select 标志='正常的进程',57spid,kpid,blocked,dbid,db_name(dbid),uid,loginame,cpu,login_time,58open_tran,status,hostname,program_name,hostprocess,nt_domain,net_address59 from master..sysprocesses60 set @count=@@rowcount61end6263if @count>064begin65 create table #t1(id int identity(1,1),a nvarchar(30),b Int,EventInfo nvarchar(255))66 if@kill_lock_spid=167 begin68 declare @spid varchar(10),@标志 varchar(10)69 while@i<=@count70 begin71 select @spid=进程ID,@标志=标志 from #t where id=@i72 insert #t1 exec('dbcc inputbuffer('+@spid+')')73 if @@rowcount=0 insert #t1(a) values(null)74 if @标志='死锁的进程' exec('kill '+@spid)75 set @i=@i+176 end77 end78 else79 while @i<=@count80 begin81 select @s='dbcc inputbuffer('+cast(进程ID as varchar)+')' from #t where id=@i82 insert #t1 exec(@s)83 if @@rowcount=0 insert #t1(a) values(null)84 set @i=@i+185 end86 select a.*,进程的SQL语句=b.EventInfo87 from #t a join #t1 b on a.id=b.id88 order by 进程ID89end90set nocount off91go。
数据库表锁死的解决方法

数据库表锁死的解决方法
数据库表锁死通常是指表级别的锁被占用,其他表中的数据无法访问的情况。
常见的解决方法有以下几种:
1. 重试锁:在锁定期间,可以不断地尝试获取锁,直到成功获取锁为止。
这种方法可以强制释放被占用的锁,使得其他表可以访问到受影响的数据。
2. 并发锁:将锁分配给并发事务,以便多个事务同时访问同一个表时,可以使用并发锁来避免竞争条件。
但是,这种方法可能会降低性能,因为多个事务需要同时等待锁。
3. 数据库级别的锁定限制:在数据库中设置锁定限制,使得可以限制对同一表的锁定时间或锁定数量等。
这种方法可以更加精确地控制锁的使用,避免锁死的问题。
4. 数据库操作日志:记录数据库操作日志,以便在出现锁死问题时,可以追溯锁定的来源和原因。
通过分析操作日志,可以找到锁死的根本原因,并采取相应的措施解决。
5. 数据库性能优化:优化数据库的性能和架构,降低锁的使用,减少锁死的可能性。
需要注意的是,解决锁死问题需要根据具体情况进行综合考虑,采取多种方法的组合来解决。
同时,解决锁死问题也需要遵守锁的使用规范,避免锁的使用不当导致锁死的问题。
数据库事务处理中的死锁与阻塞解决方案

数据库事务处理中的死锁与阻塞解决方案在数据库系统中,事务是指一组操作被视为一个不可分割的工作单位,它要么完全执行,要么完全不执行。
然而,复杂的事务处理环境中,常常会出现死锁和阻塞的问题。
本文将介绍数据库事务处理中死锁和阻塞的原因,并提供一些解决方案。
一、死锁死锁是指两个或多个事务互相请求对方所持有的资源,而导致所有事务无法继续执行的状态。
死锁的发生通常由于以下四个必要条件同时满足而产生:1. 互斥条件:每个资源只能由一个事务占用;2. 非抢占条件:事务不能抢占已被其他事务占用的资源;3. 占用且等待条件:事务在等待其他事务所持有的资源同时继续持有已占用的资源;4. 循环等待条件:存在一个资源占用的循环等待链。
解决死锁问题的常用方法包括死锁检测与死锁恢复。
1. 死锁检测:使用图论中的“循环检测”算法,根据已占用和等待的资源情况,在资源依赖图中检测循环链路。
一旦发现死锁,可以通过终止部分事务,使其他事务继续执行来解开死锁。
2. 死锁恢复:死锁恢复的方法有撤销(回滚)事务和使用死锁预防技术,如超时机制和死锁检测与恢复算法。
撤销(回滚)事务是指中止并撤销某些事务的操作,以解开死锁。
超时机制是指设置一个事务等待资源的最长时间,若超过该时间则主动放弃该事务以避免死锁。
死锁检测与恢复算法是一套专门处理死锁问题的算法,可以在发现死锁时选择牺牲少数事务,使其他事务可以继续执行。
二、阻塞阻塞是指一个事务无法执行下一步操作,因为所请求的资源被其他事务占用。
阻塞的产生可能是由于资源短缺或事务运行顺序不当引起。
解决阻塞问题的主要方法包括资源预分配和事务调度技术。
1. 资源预分配:为了避免出现由于资源不足而导致的阻塞问题,可以在事务开始前预先分配所有需要的资源。
这样可以消除潜在的资源竞争,提高系统的并发性。
但是,预分配资源可能导致资源的浪费和空间的占用。
2. 事务调度技术:采用某种策略对事务的顺序进行调度,优化资源的利用,避免阻塞。
如何处理数据库中的死锁问题(一)

处理数据库中的死锁问题在数据库管理系统中,死锁是一种常见的问题,它指的是两个或多个事务无限期地等待对方持有的资源,导致系统无法继续进行下去。
解决死锁问题是数据库管理人员和开发人员必须面对和解决的挑战之一。
本文将介绍如何处理数据库中的死锁问题。
一、了解死锁的原因和类型在解决数据库中的死锁问题之前,我们首先需要了解死锁的原因和类型。
死锁通常发生在并发事务环境中,其中每个事务都需要访问共享资源。
出现死锁的原因可以归结为以下几点:资源竞争、事务顺序死锁和事务等待。
在资源竞争中,多个事务同时请求相同的资源,但只能有一个事务能够成功获取该资源,其他事务必须等待。
当多个事务出现循环的资源请求关系时,便会形成事务顺序死锁。
事务等待则是指事务 A 等待事务 B 持有的资源,同时事务 B 又等待事务 A 持有的资源。
二、使用事务和锁机制为了避免死锁问题的发生,我们可以使用事务和锁机制。
事务是数据库管理系统中的一组操作,这些操作一起执行或一起失败。
通过使用事务,我们可以减少事务之间的竞争,从而减少死锁的可能性。
在事务中,锁是一种重要的机制,用于控制对共享资源的访问。
我们可以使用排他锁(Exclusive Lock)和共享锁(Shared Lock)来保护资源。
排他锁允许一个事务独占地访问资源,而共享锁允许多个事务共享访问资源。
在设计数据库模式时,我们可以通过良好的索引设计来减少死锁的可能性。
合理的索引设计可以减少资源竞争,提高事务的并发性。
三、使用超时机制和重试策略另一种处理数据库中的死锁问题的方法是使用超时机制和重试策略。
当一个事务等待超过一定的时间后,我们可以判断该事务可能陷入了死锁,并取消该事务的执行。
通过设置合理的超时时间,我们可以减少死锁对系统性能的影响。
此外,重试策略也是一个有效的处理死锁问题的方法。
当一个事务因为死锁而失败时,我们可以将其标记为失败并稍后重试。
通过重试策略,我们可以在多次尝试之后成功完成事务的执行,从而避免死锁的发生。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Sybase 数据库死锁对策
死锁的发生对系统的性能和吞吐量都有重要影响,经检测发现,管理信息系统的死锁主要是因为两个或多个线程(登录)抢占同一表数据资源。
引起长时间抢占同一资源不是因为我们需要处理的事务太复杂,时间太长,而往往是因为我们在前端应用程序对数据库作操作时忘了提交.本文介绍一种处理解决这种死锁的方法。
Sybase 封锁原理
数据共享与数据一致性是一对不可调和的矛盾,为了达到数据共享与数据一致,必须进行并发控制。
并发控制的任务就是为了避免共享冲突而引起的数据不一致。
Sybase SQL Server 并发控制的方法是加锁机制(LOCKING ). 锁的类型
Sybase SQL Server 有三种封锁类型:排它锁(exclusive lock,简称X 锁);共享锁(share lock,简称S 锁);更新锁(update lock,简称U
锁)。
这三种锁的相容矩阵表如下:
×:表示不兼容。
∨:表示兼容。
Sybase SQL Server 是自动决定加锁类型的。
一般来说,
读(SELECT )操作使用S 锁,写(UPDATE,INSERT 和delete )操作使用X 锁。
U 它在一个更新操作开始时获得,当要修改这些页时,U 锁会升级为X 锁。
锁的力度
SQL Server 有两级锁:页锁和表锁。
通常页锁比表锁的限制更少(或更小)。
页锁对本页的所有行进行锁定,而表锁则锁定整个表。
为了减小用户间的数据争用和改进并发性,SQL Server 试图尽可能地使用页锁。
当SQL Server 决定一个语句将访问整个表或表的大多数页时,它用表锁来提供更有效的锁定。
锁定策略直接受查询方案约束,如果update 或delete 语句没有可用的索引,它就执行表扫描或请求一个表锁定。
如果update 或delete 语句使用了索引,它就通过请求页锁来开始,如果影响到大多数行,它就要请求表锁。
一旦一个语句积累的页锁超过锁提升阈值,SQL Server 就设法给该对象分配一个表锁。
如果成功了,页锁就不再必要了,因此被释放。
表锁也在页层提供避免锁冲突的方法。
对于有些命令SQL Server 自动使用表锁。
锁的状态
SQL SERVER 加锁有三种状态:
1)意向锁(intend )—是一种表级锁,它表示在一个数据页上获得一个S 或X 锁的意向。
意向锁可以防止其他事务在该数据页的表上获得排它锁。
2)阻塞(blocking,简记blk )—它表明目前加锁进程的状态,带有blk 后缀的锁说明该进程目前正阻塞另一个需要获得锁的进程,只有这一进程完成,其他进程才可以进行。
3)需求锁(demand )—表示此时该进程企图得到一个排它锁。
它可以防止 可申请的锁 已有的锁 S U X S ∨ ∨ × U ∨ × × X
× × ×
在这一表或页上加过多的S锁,她表示某一事务是下一个去锁定该表和该页的事务。
需求锁是一个内部过程,因此用sp_lock是无法看见的。
死锁DEADLOCK
简单地说,有两个用户进程,每个进程都在一个单独的页或表上有一个锁,而且每个进程都想在对方进程的页或表上请求不相容锁时就会发生“死锁”。
在这种情况下,第一个进程在等待另一进程释放锁,但另一进程要等到第一个进程的对象释放时才会释放自己的锁。
SQL Server检查是否死锁,并终止事务中CPU时间积累最小的用户(即最后进入的用户)。
SQL Server回滚该用户的事务,并用消息号1205通知有此死锁行为的应用程序,然后允许其他用户进程继续进行。
在多用户情形下,每个用户的应用程序都应检查每个修改数据的事务是否有1205号消息,以此确定是否有可能死锁。
消息号1025表示该用户的事务因死锁而终止并被回滚。
应用程序必须重新开始这个事务处理。
查找死锁原因
既然管理信息系统长时间死锁的原因是由于我们提交或者是提交不当,那么我们就可以通过修改程序防止出现死锁。
定位死锁出错处主要经过以下三步:1)在死锁出现时,用SP_WHO,SP_LOCK获得进程与锁的活动情况。
2)结合库表sysobjects和相应的操作员信息表查出被锁的库表与锁住别人的操作员。
3)根据锁定的库表与操作员的岗位,可以估计出程序大约出错处。
询问操作员在死锁时执行的具体操作即可完全定位出错处。
最后查找程序并修改之。
用sp_who获取关于被阻碍进程的信息
系统过程sp_who给出系统进程的报告。
如果用户的命令正被另一进程保持的锁阻碍,则:
◆status列显示“lock sleep”。
◆blk列显示保持该锁或这些锁的进程标识,即被谁锁定了。
◆lo giname列显示登录操作员。
结合相应的操作员信息表,便可知道操作员是谁。
Fid spid status loginame origname blk dbname cmd
0 1 lock sleep lm lm 18 QJYD SELECT
0 2 sleeping NULL NULL 0 master NETWORK HANDLER
0 3 sleeping NULL NULL 0 master NETWORK HANDLER
……
用sp_lock浏览锁
要得到关于当前SQL Server上保持的锁的报告,可用系统过程sp_lock [spid1[,spid2]],spid1,spid2是表master.dbo.sysprocesses中的sql server 进程id号,用sp_who可以得到锁定与被锁定的spid号:
◆locktype列显示加锁的类型和封锁的粒度,有些锁的后缀还带有blk表
明锁的状态。
前缀表明锁的类型:Sh—共享锁,Ex—排它锁或更新锁,中间表明锁死在表上(”table”或’intent’)还是在页上(page). 后缀“blk”表明该进程正在障碍另一个需要请求锁的进程。
一旦正在障碍的进程一结束,其他进程就向前移动。
“demand”后缀表明当前共享锁一释放,该进程就申请互斥锁。
◆table_id列显示表的id号,结合sysobjects即可查出被封锁的表名。
执行该进程后屏幕显示
Fid Spid locktype table_id page row dbname Class context
0 1 Sh_intent 678293476 0 0 QJYD Non Cursor LockFam dur
0 1 Sh_page 678293476 31764 0 QJYD Non Cursor Lock
0 18 Ex_intent 9767092 0 0 QJYD Non Cursor LockFam dur
……
定位出错处
根据sp_who与sp_lock命令的结果,结合sysobjects和相应的操作员信息表。
得到操作员及其在死锁时所操作的库表,便大约可以知道应用程序的出错处,再询问操作员在死锁时执行什么操作以进一步认证。
最后查找程序并修正之。