将列更改为非null时避免使用ORA-00054

时间:2017-07-17 13:46:10

标签: sql oracle ddl

我希望在将现有列更改为" not null"时避免出现以下错误或任何其他错误消息。在沉重的二手桌上:

SQL Error: ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired
00054. 00000 -  "resource busy and acquire with NOWAIT specified or timeout expired"
*Cause:    Interested resource is busy.
*Action:   Retry if necessary or increase timeout.

我的Oracle版本是:Oracle Database 12c企业版12.1.0.2.0版 - 64位生产版。我尝试使用独占锁,如下所示,但我仍然得到错误。我通过在其他会话中做一些DML来模拟一个繁重的使用过的表。

第一节

create table iei1731 (
  col1 varchar2(1 char),
  col2 number(1,0)
);
insert into iei1731 (col1, col2) values ('1', 0);
commit;
update iei1731 set col1 = col1 where col1 = '1';

第二节

lock table iei1731 in exclusive mode;

第一节

rollback; -- now session 2 gets the exclusive lock on the table
update iei1731 set col1 = col1 where col1 = '1';

第二节

alter table iei1731 modify col2 not null; -- here I get the ORA-00054

第1节(清理)

rollback;
drop table iei1731;

所以我的问题是,是否有可能将这个繁重的使用表上的列设置为不为null而没有任何错误消息?

2 个答案:

答案 0 :(得分:1)

使用DDL_LOCK_TIMEOUT让会话等待锁定:

--Wait up to 10 minutes to acquire the lock.
alter session set DDL_LOCK_TIMEOUT=600;
alter table iei1731 modify col2 not null;

答案 1 :(得分:0)

如果它被独占锁定 - 否 - 锁定必须先释放。

同样进行非空更改是元数据更改,因此您将创建一个可能的行缓存'如果此对象被大量访问则锁定,并且该行缓存锁将使其他人在队列中等待对象访问,直到您的not null成功为止。在繁忙的生产环境中,这可能会导致令人讨厌的等待雪球。最好在停机或不太繁忙的时候进行元数据更改。