oracle教程之死锁

假设当前存在两个session(以A和C来表示),如果A持有C正在申请的锁定,同时C也持有A正在申请的锁定时,这时发生死锁现象。死锁是典型的“双输”情 况,如果任其发展,则会出现A和C这两个session正在执行的事务都无法结束的现象。因此,在Oracle数据库中,造成死锁的那个DML语句会被撤销。死锁总 是由于应用程序设计不合理引起的。

 

我们来看一个例子,先启动一个session,发出如下的语句:

SQL> select sid from v$mystat where rownum=1;

SID

----------

159

SQL> update employees set last_name=last_name||'a'

where employee_id=100;

1 row updated.

 

我们再启动一个session:

SQL> select sid from v$mystat where rownum=1;

SID

----------

158

SQL> update employees set last_name=last_name||'b' where

employee_id=101;

1 row updated.

 

然后,我们在159号session中,更新employee_id为101的记录:

SQL> update employees set last_name=last_name||'c'

where employee_id=101;

 

毫无疑问,由于该记录上的锁定正由158号session持有,因此159号session进入队列进行等待。然后我们在158号session上更新employee_id为100的记录:

SQL> update employees set last_name=last_name||'d' where employee_id=100;

 

这时,158号和159号session各自持有对方申请的锁定,因此出现死锁现象。Oracle会自动监测该现象,一旦发现该现象,我们会发现159号session的更新被 自动中断:

SQL> update employees set last_name=last_name||'c' where

employee_id=101;

update employees set last_name=last_name||'c' where employee_id=101

*

ERROR at line 1:

ORA-00060: deadlock detected while waiting for resource

同时会在alert<SID>.log文件中记录该事件:

Sat Dec 15 01:19:20 2007

ORA-00060: Deadlock detected. More info in file /u01/app/

oracle/admin/ora10g/udump/ora10g_ ora_3813.trc.

 

也就是说,当某个session的事务引起了死锁时,Oracle会自动将阻塞该事务的其他事务中相应的DML语句撤销,而阻塞该事务的其他事务中的其他DML语句并 没有撤销。表现在上面的例子中,也就是159号session中更新employee_id为101的语句被撤销了,但是最早发出的更新employee_id为100的语句并没有被撤 销。

你可能感兴趣的:(oracle,oracle,oracle,Lock,死锁)