ORA-02049: timeout: distributed transaction waiting for lock
以上为项目中遇到的问题,此问题导致应用无法访问
以下为网上的说明:
02049, 00000, "timeout: distributed transaction waiting for lock"
// *Cause: exceeded INIT.ORA distributed_lock_timeout seconds waiting for lock.
// *Action: treat as a deadlock
DISTRIBUTED_LOCK_TIMEOUT默认是60秒:
SQL> show parameter DISTRIBUTED_LOCK_TIMEOUT
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
distributed_lock_timeout integer 60
SQL> alter system set DISTRIBUTED_LOCK_TIMEOUT=300;
alter system set DISTRIBUTED_LOCK_TIMEOUT=300
*
ERROR at line 1:
ORA-02095: specified initialization parameter cannot be modified
SQL> alter system set DISTRIBUTED_LOCK_TIMEOUT=300 scope=spfile;
System altered.
SQL>
Example:
Session 1 Session 2
~~~~~~~~~ ~~~~~~~~~
update t2@LINK set b=4 where b=3;
select * from dual@LINK ;
update t2 set b=4 where b=3;
^^ ORA 2049
OR EVEN
update t2 set b=4 where b=3;
select * from dual@LINK ;
update t2 set b=4 where b=3;
^^ ORA 2049
下面是一些实验步骤:
不用PL/SQL Developer的command window了,直接用sqlplus,开两个session,分别为session 1和session 2。
先在session 1中删除表uplbth中的一条记录:
Session 1:
SQL> delete from uplbth where ubtbth='HPCAN081200010';
已删除1行。
接着在session 2中也做同样的删除动作,只不过在执行删除前先执行一个带dblink的query语句:
Session 2:
SQL>select count(*) from uplbth@caipratest;
COUNT(*)
----------
36
SQL> delete from uplbth where ubtbth='HPCAN081200010';
delete from uplbth where ubtbth='HPCAN081200010'
*
第1行出现错误:
ORA-02049: timeout: distributed transaction waiting for lock
在session 2大概等待了一分钟后,oracle这里报错ORA-02049,这就是最好的证明,如若"select count(*) from uplbth@caipratest"不起一个distributed transaction的话,session 2是会一直等待下去的。
这里为什么会等待一分钟,是因为distributed_lock_timeout的值是60(这也是默认值)。
好了,我们这里再来看一下为什么在PL/SQL Developer的command window中做同样的事情,session 2就会一直等待session 1?
我感觉这是因为在session 2中执行"select count(*) from uplbth@caipratest"的时候PL/SQL Developer人为的commit了一下。