您好,欢迎访问一九零五行业门户网

ORA-00060的示例与若干场景

对于批量更新,和上面一个事务中多个表操作的原理相同,并发大则也会导致deadlock。要么减少并发,要么不用批量更新。其实出现de
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
------------------ ---------- ----------
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 or rollback statement or implicitly when a ddl statement is issued.
比如:
session1:
update table1,update table2 ...
session2:
delete table2, delete table1 ...
此时碰巧可能出现互相持有对方需要的资源,导致deadlock。
对于这种情况,可能的解决方法就是:将表的顺序改为一致,或者拆分更小的事务,避免较差更新的情况。
其它类似信息

推荐信息