数据库死锁及解决死锁问题

deadlocks(死锁

所谓死锁<DeadLock>: 是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去.此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程.由于资源占用是互斥的,当某个进程提出申请资源后,使得有关进程在无外力协助下,永远分配不到必需的资源而无法继续运行,这就产生了一种特殊现象死锁。 一种情形,此时执行程序中两个或多个线程发生永久堵塞(等待),每个线程都在等待被其他线程占用并堵塞了的资源。例如,如果线程A锁住了记录1并等待记录2,而线程B锁住了记录2并等待记录1,这样两个线程就发生了死锁现象。计算机系统中,如果系统的资源分配策略不当,更常见的可能是程序员写的程序有错误等,则会导致进程因竞争资源不当而产生死锁的现象。锁有多种实现方式,比如意向锁,共享-排他锁,锁表,树形协议,时间戳协议等等。锁还有多种粒度,比如可以在表上加锁,也可以在记录上加锁。 
产生死锁的原因主要是:(1) 因为系统资源不足。(2) 进程运行推进的顺序不合适。(3) 资源分配不当等。
如果系统资源充足,进程的资源请求都能够得到满足,死锁出现的可能性就很低,否则就会因争夺有限的资源而陷入死锁。其次,进程运行推进顺序与速度不同,也可能产生死锁。产生死锁的四个必要条件:(1) 互斥条件:一个资源每次只能被一个进程使用。
(2) 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
(3) 不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。
(4) 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。这四个条件是死锁的必要条件,只要系统发生死锁,这些条件必然成立,而只要上述条件之一不满足,就不会发生死锁。死锁的解除与预防: 
理解了死锁的原因,尤其是产生死锁的四个必要条件,就可以最大可能地避免、预防和
解除死锁。所以,在系统设计、进程调度等方面注意如何不让这四个必要条件成立,如何确定资源的合理分配算法,避免进程永久占据系统资源。此外,也要防止进程在处于等待状态的情况下占用资源,在系统运行过程中,对进程发出的每一个系统能够满足的资源申请进行动态检查,并根据检查结果决定是否分配资源,若分配后系统可能发生死锁,则不予分配,否则予以分配 。因此,对资源的分配要给予合理的规划。

如何将死锁减至最少

虽然不能完全避免死锁,但可以使死锁的数量减至最少。将死锁减至最少可以增加事务的吞吐量并减少系统开销,因为只有很少的事务:

◆回滚,而回滚会取消事务执行的所有工作。

◆由于死锁时回滚而由应用程序重新提交。

下列方法有助于最大限度地降低死锁:

◆按同一顺序访问对象。

◆避免事务中的用户交互。

◆保持事务简短并在一个批处理中。

◆使用低隔离级别。

◆使用绑定连接。

按同一顺序访问对象

如果所有并发事务按同一顺序访问对象,则发生死锁的可能性会降低。例如,如果两个并发事务获得 Supplier 表上的锁,然后获得 Part 表上的锁,则在其中一个事务完成之前,另一个事务被阻塞在 Supplier 表上。第一个事务提交或回滚后,第二个事务继续进行。不发生死锁。将存储过程用于所有的数据修改可以标准化访问对象的顺序。

避免事务中的用户交互

避免编写包含用户交互的事务,因为运行没有用户交互的批处理的速度要远远快于用户手动响应查询的速度,例如答复应用程序请求参数的提示。例如,如果事务正在等待用户输入,而用户去吃午餐了或者甚至回家过周末了,则用户将此事务挂起使之不能完成。这样将降低系统的吞吐量,因为事务持有的任何锁只有在事务提交或回滚时才会释放。即使不出现死锁的情况,访问同一资源的其它事务也会被阻塞,等待该事务完成。

保持事务简短并在一个批处理中

在同一数据库中并发执行多个需要长时间运行的事务时通常发生死锁。事务运行时间越长,其持有排它锁或更新锁的时间也就越长,从而堵塞了其它活动并可能导致死锁。

保持事务在一个批处理中,可以最小化事务的网络通信往返量,减少完成事务可能的延迟并释放锁。

使用低隔离级别

确定事务是否能在更低的隔离级别上运行。执行提交读允许事务读取另一个事务已读取(未修改)的数据,而不必等待第一个事务完成。使用较低的隔离级别(例如提交读)而不使用较高的隔离级别(例如可串行读)可以缩短持有共享锁的时间,从而降低了锁定争夺。

使用绑定连接

使用绑定连接使同一应用程序所打开的两个或多个连接可以相互合作。次级连接所获得的任何锁可以象由主连接获得的锁那样持有,反之亦然,因此不会相互阻塞。

用存储过程查出引起死锁的进程和SQL语句

假如发生了死锁,我们怎么去检测具体发生死锁的是哪条SQL语句或存储过程?此时我们可以使用以下存储过程来检测,就可以查出引起死锁的进程和SQL语句。

<ccid_nobr>

<ccid_code>use mastergocreate procedure sp_who_lockasbegindeclare @spid int,@bl int,@intTransactionCountOnEntry int,@intRowcount int,@intCountProperties int,@intCounter intcreate table #tmp_lock_who (id int identity(1,1),spid smallint,bl smallint)IF @@ERROR<>0 RETURN @@ERRORinsert into #tmp_lock_who(spid,bl) select. 0 ,blockedfrom (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>0IF @@ERROR<>0 RETURN @@ERROR -- 找到临时表的记录数select. @intCountProperties = Count(*),@intCounter = 1from #tmp_lock_whoIF @@ERROR<>0 RETURN @@ERROR if @intCountProperties=0select. ‘现在没有阻塞和死锁信息‘ as message-- 循环开始while @intCounter <= @intCountPropertiesbegin-- 取第一条记录select. @spid = spid,@bl = blfrom #tmp_lock_who where Id = @intCounter beginif @spid =0 select. ‘引起数据库死锁的是: ‘+ CAST(@bl AS VARCHAR(10)) + ‘进程号,其执行的SQL语法如下‘elseselect. ‘进程号SPID:‘+ CAST(@spid AS VARCHAR(10))+ ‘被‘ + ‘进程号SPID:‘+ CAST(@bl AS VARCHAR(10)) +‘阻塞,其当前进程执行的SQL语法如下‘DBCC INPUTBUFFER

与锁定有关的两个问题--死锁和阻塞

死锁

死锁是一种条件,不仅仅是在关系数据库管理系统 (RDBMS) 中发生,在任何多用户系统中都可以发生的。当两个用户(或会话)具有不同对象的锁,并且每个用户需要另一个对象的锁时,就会出现死锁。每个用户都等待另一个用户释放他的锁。当两个连接陷入死锁时,Microsoft® SQL Server™ 会进行检测。其中一个连接被选作死锁牺牲品。该连接的事务回滚,同时应用程序收到错误。

如果死锁变成单个公用事件,而且它们的回滚造成过多的性能降级,那么就需要再次进行深入彻底的调查。使用跟踪标记 1204。例如,下面的命令从命令提示符启动 SQL Server,并启用跟踪标记 1204:

c:\\mssql\\binn\\sqlservr -T1204

现在所有消息都会显示在启动 SQL Server 的控制台屏幕上和错误日志中。

使用分布式事务时,也可能发生死锁。

阻塞

任何基于锁的并发系统都不可避免地具有可能在某些情况下发生阻塞的特征。当一个连接控制了一个锁,而另一个连接需要冲突的锁类型时,将发生阻塞。其结果是强制第二个连接等待,或在第一个连接上阻塞。

在本主题中,术语"连接"是指数据库的单个登录会话。每个连接都作为系统进程 ID (SPID) 出现。尽管每一个 SPID 一般都不是单独的进程上下文,但这里常常用来指一个进程。更确切的说,每个 SPID 都是由服务器资源和数据结构(为给定客户单个连接的请求提供服务)组成。单个客户应用程序可能有一个或多个连接。就 SQL Server 而言,从单个客户机上的单个客户应用程序来的多个连接和从多个客户应用程序或多个客户机来的多个连接是没有区别的。不管是来自同一应用程序还是来自两台不同客户机上单独的应用程序,一个连接都可以阻塞另一个连接。

时间: 2024-11-06 11:24:37

数据库死锁及解决死锁问题的相关文章

定位数据库死锁,和初步解决死锁办法(后发制人)

1.目前我只是在sql 2008上实验成功: 在数据库开启跟踪标识: DBCC TRACEON(1204,-1)DBCC TRACEON(1222,-1) 这两个跟踪标记都是将死锁写到错误日志中,不过1204是以文本格式进行,而1222是以XML格式保存. 开启后通过查看数据库日志文件就可以找到是那个语句引发死锁. 1.模拟一个死锁: 1 DBCC TRACEON(1204,-1) 2 DBCC TRACEON(1222,-1) 3 4 CREATE TABLE Lock1(C1 int def

数据库死锁的解决办法

数据库死锁的解决办法 近日在博客网站上,回复别人的数据库死锁避免问题,之前也曾经几次答复过同样的内容,觉得很有必要汇聚成一个博客文章,方便大家. 这里的办法,对所有的数据库都适用. 这个解决办法步骤如下: 1. 每个表中加 updated_count (integer) 字段 2. 新增一行数据,updated_count =0 :insert into table_x (f1,f2,...,update_count) values(...,0); 3. 根据主键获取一行数据 SQL,封装成一个

数据库中锁有哪些,遇到死锁怎么解决

锁的概念: 首先我们先了解下什么是数据库锁, 锁是事务对某个数据库中的资源(如表和记 录)存取前,先向系统提出请求,封锁该资源, 事务获得锁后,即取得对数据的控制权,在事务释放它的锁之前,其他事务不能更新此数据.当事务撤消后,释放被 锁定的资源. 数据库锁的分类: 共享锁:又叫S锁或者读锁,加了共享锁的数据对象可以被其他事务读取,但不能修改, 通常是该数据对象被读取完毕,锁立即被释放 排他锁:又叫X锁或者写锁,当数据对象被加上排它锁时,一个事务必须得到锁才能对该数据对象进行访问,一直到事务结束锁

巧用MySQL InnoDB引擎锁机制解决死锁问题(转)

该文会通过一个实际例子中的死锁问题的解决过程,进一步解释innodb的行锁机制 最近,在项目开发过程中,碰到了数据库死锁问题,在解决问题的过程中,笔者对MySQL InnoDB引擎锁机制的理解逐步加深. 案例如下: 在使用Show innodb status检查引擎状态时,发现了死锁问题: *** (1) TRANSACTION: TRANSACTION 0 677833455, ACTIVE 0 sec, process no 11393, OS thread id 278546 starti

SQLServer查看和解决死锁的方法

在master数据库中新建以下存储过程 --处理死锁-- 查看当前进程,或死锁进程,并能自动杀掉死进程-- 因为是针对死的,所以如果有死锁进程,只能查看死锁进程-- 当然,你可以通过参数控制,不管有没有死锁,都只查看死锁进程--调用示例 exec p_lockinfo create proc [dbo].[p_lockinfo]@kill_lock_spid bit=1, --是否杀掉死锁的进程,1 杀掉, 0 仅显示@show_spid_if_nolock bit=1 --如果没有死锁的进程,

SQL Server中解决死锁的新方法介绍

SQL Server中解决死锁的新方法介绍 数据库操作的死锁是不可避免的,本文并不打算讨论死锁如何产生,重点在于解决死锁,通过SQL Server 2005, 现在似乎有了一种新的解决办法. 将下面的SQL语句放在两个不同的连接里面,并且在5秒内同时执行,将会发生死锁. <ccid_nobr> <ccid_code>use Northwindbegin tran insert into Orders(CustomerId) values(@#[email protected]#)

SQL Server中解决死锁

SQL Server中解决死锁的新方法介绍 数据库操作的死锁是不可避免的,本文并不打算讨论死锁如何产生,重点在于解决死锁,通过SQL Server 2005, 现在似乎有了一种新的解决办法. 将下面的SQL语句放在两个不同的连接里面,并且在5秒内同时执行,将会发生死锁. <ccid_nobr> <ccid_code>use Northwindbegin tran insert into Orders(CustomerId) values(@#[email protected]#)

DB2死锁的解决办法

db2 get snapshot for locks on sampledb2 get db cfg for sampledb2 update db cfg using dlchktime 10000 -查看数据库管理器级别快照信息     db2 get snapshot for dbm -查看数据库级别快照信息     db2 get snapshot for database on dbname        -查看应用级别快照信息     db2 get snapshot for app

进程死锁及解决办法

操作系统 2009-09-24 16:48:58 阅读767 评论1   字号:大中小 订阅 一.要点提示 (1) 掌握死锁的概念和产生死锁的根本原因. (2) 理解产生死锁的必要条件--以下四个条件同时具备:互斥条件.不可抢占条件.占有且申请条件.循环等待条件. (3) 记住解决死锁的一般方法,掌握死锁的预防和死锁的避免二者的基本思想. (4) 掌握死锁的预防策略中资源有序分配策略. (5) 理解进程安全序列的概念,理解死锁与安全序列的关系. (6) 了解银行家算法. (7) 了解资源分配图.