日期:2014-05-16  浏览次数:20547 次

ORA-00060的示例与若干场景
  create table eg_60 ( num number, txt varchar2(10) );

  insert into eg_60 values ( 1, 'First' );

  insert into eg_60 values ( 2, 'Second' );

  SQL> select rowid, num, txt from eg_60;

  ROWID NUM TXT 查看更多关于oracle数据库的疑问,可关注cuug每周五晚免费网络公开课。

  ------------------ ---------- ----------

  AAAQT2AAHAAAEdYAAA 1 First

  AAAQT2AAHAAAEdYAAB 2 Second

  Session1:

  update eg_60 set txt='ses1' where num=1;

  Session2:

  update eg_60 set txt='ses2' where num=2;

  update eg_60 set txt='ses2' where num=1;

  Session1:

  update eg_60 set txt='ses1' where num=2;

  此时Session2报的错:

  update eg_60 set txt='ses2' where num=1

  *

  ERROR at line 1:

  ORA-00060: deadlock detected while waiting for resource

  Session1的update eg_60 set txt='ses1' where num=2;仍处hang状态,此时Session2执行exit正常退出,则

  Session1:

  update eg_60 set txt='ses1' where num=2;

  1 row updated.

  原因就是正常退出,Oracle的PMON会自动rollback所做的未Commit操作,释放了num=2的资源,因此Session1可以执行。

  出现60错误会产生一个trace文件,查看trace文件位置:

  show parameter user_dump

  NAME TYPE VALUE

  ------------------------------------ ----------- ------------------------------

  user_dump_dest string /opt/app/ora10g/admin/petest/udump

  查看trace文件:

  Deadlock graph:

  ---------Blocker(s)-------- ---------Waiter(s)---------

  Resource Name process session holds waits process session holds waits

  TX-00090004-00019887 25 478 X 24 459 X

  TX-000a002d-00032a8d 24 459 X 25 478 X

  session 478: DID 0001-0019-00027AEC session 459: DID 0001-0018-000CDDD8

  session 459: DID 0001-0018-000CDDD8 session 478: DID 0001-0019-00027AEC

  Rows waited on:

  Session 459: obj - rowid = 000104F6 - AAAQT2AAHAAAEdYAAB

  (dictionary objn - 66806, file - 7, block - 18264, slot - 1)

  Session 478: obj - rowid = 000104F6 - AAAQT2AAHAAAEdYAAA

  (dictionary objn - 66806, file - 7, block - 18264, slot - 0)

  Information on the OTHER waiting sessions:

  Session 459:

  pid=24 serial=34722 audsid=899246 user: 65/DCSOPEN

  O/S info: user: dcsopen, term: pts/0, ospid: 8838, machine: vm-vmw4131-t

  program: sqlplus@vm-vmw4131-t (TNS V1-V3)

  application name: SQL*Plus, hash value=3669949024

  Current SQL Statement:

  update eg_60 set txt='ses1' where num=2

  End of information on OTHER waiting sessions.

  Current SQL statement for this session:

  update eg_60 set txt='ses2' where num=1

  ===================================================

  这里66806代表的OBJECT_ID对应object是eg_60。当前执行的SQL是update eg_60 set txt='ses2' where num=1,是这条SQL报的60错误,原因是由于update eg_60 set txt='ses1' where num=2这条SQL。因为这里是在同一台机器开的两个session,如果是不同机器客户端访问数据库做的这个实验,就可以根据machine: vm-vmw4131-t知道是哪个客户端执行的这条SQL。

  通过PROCESS STATE节中O/S info: user: dcsopen, term: pts/1, ospid: 13112, machine: vm-vmw4131-t也可以知道是哪个客户端执行SQL报的60错误。

  以上是同一张表不同session之间产生的死锁。还有另外一种场景,也是之前这边应用碰到的问题,即不同表之间的死锁,刚刚初步得解的,其实上述两种都属于事务级别的死锁,这里可能说的不准确,就是因为执行一个SQL后没有commit或rollback,再执行另外一个SQL,这两个SQL形成一个事务,造成可能的死锁。

  关于事务,Concept中的解释:

  A transaction is a logical unit of work that contains one or more SQL statements. A transaction is an atomic unit. The effects of all the

  SQL statements in a transaction can be either all committed (applied to the database) or all rolled back (undone from the database).

  A transaction begins with the first executable SQL statement. A transaction ends when it is committed or rolled back, either explicitly

  with a COMMIT o