①.、避免一个线程同时获取多个锁.
什么是死锁
当两个(或多个)用户互相等待被对方加锁的资源时就会发生死锁(deadlock).死锁将导致相关的事务停止执行.下图演示了产生死锁的两个事务.
如图所示,在时间点 A,两个事务均获得了更新操作所需数据行上的锁,此时两事务均正常,能够继续执行.此时此刻呢,两个事务均要更新当前被对方加锁的数据.所以呢,在时间点 B 将发生死锁,因为此时两个事务都不能获得继续执行或终止所需的资源.无论两个事务等待多久,相互冲突的锁都无法被释放,所以此种情况被称为死锁.
图:产生死锁的两个事务
检测死锁
数据库能自动地检测死锁的情况,回滚造成死锁的某个语句,以便释放冲突的行级锁,从而解决死锁问题.数据库将向执行了语句级回滚的事务返回一个错误信息.
避免死锁
如果两个事务需要访问相同的一组表,那么在两个事务中按相同的顺序对这组表加锁通常能避免多表死锁.例如,如果系统中的一个主表及一个明细表都需要更新时,开发者应该遵从一定的规则,如先对主表加锁,再对明细表加锁.如果能够仔细设计类似的规则并严格执行,就能从根本上杜绝死锁的产生. 如果开发者预先知道需要在同一事务内对一系列资源加锁,那么应考虑首先对排他性最高的资源加锁.
关于数据库死锁的检查方法
第一段:数据库死锁的现象
第二段:死锁的原理
当对于数据库某个表的某一列做更新或删除等操作,执行完毕后该条语句不提
交,另一条对于这一列数据做更新操作的语句在执行的时候就会处于等待状态,
此时的现象是这条语句一直在执行,但一直没有执行成功,也没有报错.
第三段:死锁的定位方法
通过检查数据库表,能够检查出是哪一条语句被死锁,产生死锁的机器是哪一台.
①.)用dba用户执行以下语句
select username,lockwait,status,machine,program from v$session where sid in
(select session_id from v$locked_object)
如果有输出的结果,则说明有死锁,且能看到死锁的机器是哪一台.字段说明:
Username:死锁语句所用的数据库用户;
Lockwait:死锁的状态,如果有内容表示被死锁.
Status: 状态,active表示被死锁
Machine: 死锁语句所在的机器.
Program: 产生死锁的语句主要来自哪个应用程序.
select sql_text from v$sql where hash_value in
(select sql_hash_value from v$session where sid in
(select session_id from v$locked_object))
第四段:死锁的解决方法
一般情况下,只要将产生死锁的语句提交就可以了,但是在实际的执行过程中.用户可
能不知道产生死锁的语句是哪一句.可以将程序关闭并重新启动就可以了.
经常在Oracle的使用过程中碰到这个问题,所以也总结了一点解决方法.
①.)查找死锁的进程:
sqlplus "/as sysdba" (sys/change_on_install)
SELECT s.username,l.OBJECT_ID,l.SESSION_ID,s.SERIAL#,
l.ORACLE_USERNAME,l.OS_USER_NAME,l.PROCESS
FROM V$LOCKED_OBJECT l,V$SESSION S WHERE l.SESSION_ID=S.SID;
alter system kill session 'sid,serial#'; (其中sid=l.session_id)
select pro.spid from v$session ses,v$process pro where ses.sid=XX and ses.paddr=pro.addr;
其中sid用死锁的sid替换: exit
ps -ef|grep spid
其中spid是这个进程的进程号,kill掉这个Oracle进程
from:
select A.SQL_TEXT, B.USERNAME, C.OBJECT_ID, C.SESSION_ID,
B.SERIAL#, C.ORACLE_USERNAME,C.OS_USER_NAME,C.Process,
''''||C.Session_ID||','||B.SERIAL#||''''
from v$sql A, v$session B, v$locked_object C
where A.HASH_VALUE = B.SQL_HASH_VALUE and
B.SID = C.Session_ID
①.、避免给一个锁嵌套上锁,在持有一个锁的时候,不要再给这个锁上锁.如果使用多个锁,使用std::lock.
扩展资料:
解决方法
在系统中已经出现死锁后,应该及时检测到死锁的发生,并采取适当的措施来解除死锁.
死锁预防.
这是一种较简单和直观的事先预防的方法.方法是通过设置某些限制条件,去破坏产生死锁的四个必要条件中的一个或者几个,来预防发生死锁.预防死锁是一种较易实现的方法,已被广泛使用.但是由于所施加的限制条件往往太严格,可能会导致系统资源利用率和系统吞吐量降低.
死锁避免.
系统对进程发出的每一个系统能够满足的资源申请进行动态检查,并根据检查结果决定是否分配资源;如果分配后系统可能发生死锁,则不予分配,否则予以分配.这是一种保证系统不进入死锁状态的动态策略.
死锁检测和解除.
先检测:这种方法并不须事先采取任何限制性措施,也不必检查系统是否已经进入不安全区,此方法允许系统在运行过程中发生死锁.但可通过系统所设置的检测机构,及时地检测出死锁的发生,并精确地确定与死锁有关的进程和资源.检测方法包括定时检测、效率低时检测、进程等待时检测等.
然后解除死锁:采取适当措施,从系统中将已发生的死锁清除掉.
这是与检测死锁相配套的一种措施.当检测到系统中已发生死锁时,须将进程从死锁状态中解脱出来.常用的实施方法是撤销或挂起一些进程,以便回收一些资源,再将这些资源分配给已处于阻塞状态的进程,使之转为就绪状态,以继续运行.死锁的检测和解除措施,有可能使系统获得较好的资源利用率和吞吐量,但在实现上难度也最大.
参考资料:死锁百度百科
Oracle数据库出现死锁的时候可以按照以下处理步骤加以解决:
第一步:尝试在sqlplus中通过sql命令进行删除,如果能够删除成功,则万事大吉!但通常情况下,出现死锁时,想通过命令行或者通过Oracle的管理工具删除有死锁的session,oracle只会将该session标记为killed,但无法清除掉,往往需要通过第二步在操作系统层级进行删除!
Connected?as?quik
SQL?select?xidusn,?object_id,?session_id,?locked_mode?from?v$locked_object;?--查死锁的对象,获取其SESSION_ID
XIDUSN?OBJECT_ID?SESSION_ID?LOCKED_MODE
----------?----------?----------?-----------
USERNAME?SID?SERIAL#
------------------------------?----------?----------
SPID
------------
第二步:进入操作系统进行删除进程,本示例的操作系统是IBM aix.
login:?root?--录入用户名
root's?Password:?--录入密码
*******************************************************************************
*?*
*?Please?see?the?README?file?in?/usr/lpp/bos?for?information?pertinent?to?*
*?this?release?of?the?AIX?Operating?System.?*
For?Windows,?at?the?DOS?Prompt:?orakill?sid?spid
以上就是土嘎嘎小编为大家整理的oracle怎么避免死锁相关主题介绍,如果您觉得小编更新的文章只要能对粉丝们有用,就是我们最大的鼓励和动力,不要忘记讲本站分享给您身边的朋友哦!!