
什么是死锁
检测到死锁后,引擎选择运行回滚开销最小的事务的会话作为死锁牺牲品,返回1205 错误,回滚死锁牺牲品的事务并释放该事务持有的所有锁,使其他线程的事务可以请求资源并继续运行。①、死锁:线程a占有资源a,线程b占有资源b,线程a申请占有资源b,同时要求占有资源b之后才释放资源a,而线程b申请占有资源a,同时要求占有资源a之后才释放资源b,这样两个线程互相永久等待对方释放资源,这就是死锁。1 定义: 不同的线程分别占用对方需要的同步资源不放弃,都在等待对方放弃自己需要的同步资源,形成线程的死锁。
如图所示,在时间点 A,两个事务均获得了更新操作所需数据行上的锁,此时两事务均正常,能够继续执行。接下来,两个事务均要更新当前被对方加锁的数据。因此,在时间点 B 将发生死锁,因为此时两个事务都不能获得继续执行或终止所需的资源。无论两个事务等待多久,相互冲突的锁都无法被释放死锁怎么解决,所以此种情况被称为死锁。
图:产生死锁的两个事务
检测死锁
能自动地检测死锁的情况,回滚造成死锁的某个语句,以便释放冲突的行级锁,从而解决死锁问题。将向执行了语句级回滚的事务返回一个错误信息。
避免死锁
如果两个事务需要访问相同的一组表,那么在两个事务中按相同的顺序对这组表加锁通常能避免多表死锁。例如,如果系统中的一个主表及一个明细表都需要更新时,开发者应该遵从一定的规则,如先对主表加锁死锁怎么解决,再对明细表加锁。如果能够仔细设计类似的规则并严格执行,就能从根本上杜绝死锁的产生。 如果开发者预先知道需要在同一事务内对一系列资源加锁,那么应考虑首先对排他性最高的资源加锁。
关于死锁的检查方法
一、死锁的现象
程序在执行的过程中,点击确定或保存按钮,程序没有响应,也没有出现报错。
二、死锁的原理
当对于某个表的某一列做更新或删除等操作,执行完毕后该条语句不提
交,另一条对于这一列数据做更新操作的语句在执行的时候就会处于等待状态,
此时的现象是这条语句一直在执行,但一直没有执行成功,也没有报错。
三、死锁的定位方法

通过检查表,能够检查出是哪一条语句被死锁,产生死锁的机器是哪一台。
1)用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: 产生死锁的语句主要来自哪个应用程序。
2)用dba用户执行以下语句,可以查看到被死锁的语句。
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的使用过程中碰到这个问题,所以也总结了一点解决方法。
1)查找死锁的进程:
sqlplus "/as sysdba" (sys/change_on_install)
>select s.sid,s.serial#,p.spid,s.client_info。select objectname=object_name(s.object_id), s.object_id, indexname=i.name, i.index_id。$query = sprintf("select * from users where username='%s' and。
l.ORACLE_USERNAME,l.OS_USER_NAME,l.PROCESS
from v$locked_object a,v$session b。select sid,serial# from v$session where sid='&sid'。sql> select sid,serial# from v$session where sid='16'。
2)kill掉这个死锁的进程:
alter system kill session ‘sid,serial#’; (其中sid=l.session_id)
alter system kill session "sid,serial#"。alter system kill session '。select 'alter system kill session '''||sid||','||serial#||'''。
3)如果还不能解决:
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 t3.object_name,
t3.object_type,
t2.username,
t2.sid,
t2.serial#,
t2.logon_time from dba_objects t3,v$locked_object t1,v$session t2
where t1.session_id = t2.sid and t3.object_id = t1.object_id
order by t2.logon_time;
select * from v$locked_object
alter system kill session '348,25133';
alter system kill session '412,37054'
select
b.file_id 文件ID号,
b.tablespace_name 表空间名,
b.bytes/1024/1024||'M'字节数,

(b.bytes-sum(nvl(a.bytes,0)))/1024/1024||'M' 已使用,
sum(nvl(a.bytes,0))/1024/1024||'M' 剩余空间,
100 - sum(nvl(a.bytes,0))/(b.bytes)*100 占用百分比
from dba_free_space a,dba_data_files b
where a.file_id=b.file_id
group by b.tablespace_name,b.file_id,b.bytes
order by b.file_id;
☉查看死锁的用户和进程:
select t2.username, t2.*, t2.serial#, t2.logon_time
from v$locked_object t1, v$session t2
where t1.session_id = t2.sid
order by t2.logon_time;
☉查看死锁的对象:
select t1.*, t2.session_id, t2.locked_mode
from dba_objects t1, v$locked_object t2
where t1.object_id = t2.object_id;
string strsql = "select spid from master..sysprocesses where dbid=db_id( '。select mother from cat as mother, cat as kitwhere kit in elements(foo.kittens)select p from namelist list, person pwhere p.name = some elements(list.names)from cat cat where exists elements(cat.kittens)from player p where 3 > all elements(p.scores)from show show where 'fizard' in indices(show.acts)。select convert(varchar(30),login_time,120) from master..sysprocesses where spid=1。
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-113610-1.html
第七舰队扫雷大队不是盖的
美国佬欺负中国海军没有实力对抗
如果缩头缩脑