DDL commands require exclusive locks on internal structures. If these locks are not available the commands return with an “ORA-00054: resource busy” error message. This can be especially frustrating when trying to modify objects that are accessed frequently. To get round this Oracle 11g includes the
DDL_LOCK_TIMEOUTparameter, which can be set at instance or session level using theALTER SYSTEMandALTER SESSIONcommands respectively.Theparameter indicates the number of seconds a DDL command should wait for the locks to become available before throwing the resource busy error message. The default value is zero, means not wait and just fire ora-0054 if session can’t get DDL lock.
在production环境上,使用也要小心,因为该pending timeout的DDL enqueue会阻塞后来的DML操作。
测试如下
1) session A 执行Update后不提交
ORACLE@ORADB:prod SQL> select * from lock_tab;
ID
———-
1
2ORACLE@ORADB:prod SQL> update lock_tab set id=3 where id=1;
1 row updated.
2)Session B 执行DDL操作,为了获得表上的exclusive lock会等待DDL_LOCK_TIMEOUT秒。
ORACLE@ORADB:prod SQL> alter table lock_tab add newcol varchar2(1);
alter table lock_tab add newcol varchar2(1)
*
ERROR at line 1:
ORA-00054: resource busy and acquire with NOWAIT specified or timeout expiredORACLE@ORADB:prod SQL> ALTER SESSION SET ddl_lock_timeout=30;
Session altered.
ORACLE@ORADB:prod SQL> set timing on
ORACLE@ORADB:prod SQL> alter table lock_tab add newcol varchar2(1);
alter table lock_tab add newcol varchar2(1)
*
ERROR at line 1:
ORA-00054: resource busy and acquire with NOWAIT specified or timeout expiredElapsed: 00:00:30.01
3)在session B等待的30秒中,Session C执行DML操作会被Session B阻塞。Session B timeout后,该DML才能执行成功。
ORACLE@ORADB:prod SQL> delete from lock_tab where id=2;
1 row deleted.
Elapsed: 00:00:24.30

