解锁oracle上的alter table约束

时间:2014-10-15 16:11:03

标签: oracle plsql

我正在尝试编写一个脚本,由没有真正了解pl / sql的客户执行,

我在PL / sql中做了很多事务来清理它们的格局,然后必须添加一些约束来防止这种情况再次发生,我在清理后自动提交,并希望通过添加完成我的PL块这些约束

唯一的问题是我无法保证在尝试向它们添加约束时不会锁定表,是否在oracle中等待解锁类型的命令?

谢谢你,对oracle的新手,似乎无法找到这个,我已经梳理了一些API,但我在时间敏感点,并且证明很难找到,当我认为它似乎是一个漂亮DB管理的常规问题

2 个答案:

答案 0 :(得分:4)

在执行任何DDL之前,在pl / sql块中的

,你应该通过execute immedaite调用:

LOCK TABLE <table_name> IN EXCLUSIVE MODE WAIT <n>; 

其中是等待的秒数。

但请记住,即使你在第一个ddl之后锁定它也会被释放,因为DDL会自动提交。因此,无法保证DDL命令列表将像在一个事务中一样逐个执行。

答案 1 :(得分:3)

命令是:

LOCK TABLE tab IN EXCLUSIVE MODE;

如果有另一个具有类似锁定的会话(不应该存在),这将无限期地等待。

您可以在DDL之前显式锁定表(使用“WAIT”),但如果您担心另一个会话持有独占锁,则不一定能解决所有问题。听起来更像是由于另一个会话中的DML事务而遇到ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired。这最终会完成,因此在ALTER TABLE之前发出上述锁定命令将对您有所帮助。请注意,如果其他地方有一个挂起的会话,LOCK TABLE命令可以无限期地等待,除非你设置了超时。

让我们举个例子:

在会话A中,我在tab

上开始了一项交易
SQL> INSERT INTO tab VALUES(...);

在会话B中,我尝试向表中添加约束。

SQL> alter table tab add constraint uk_name unique(name);
alter table tab add constraint uk_name unique(name)
            *
ERROR at line 1:
ORA-00054: resource busy and acquire with NOWAIT specified or timeout expire

所以我得再试一次。但是,如果您在DDL之前使用LOCK ... EXCLUSIVE(WAIT)

SQL> lock table tab in exclusive mode;

-- indefinite period while the session A transaction blocks session B    

然后会话A提交或回滚

SQL> commit;

当我们看到锁定命令返回Table(s) locked

时,会话B立即继续
Table(s) Locked.

SQL> alter table tab add constraint uk_name unique(name);

Table altered.  (**comment Lock is released by the implicit commit issued the DDL statement)

SQL>

由于DDL语句释放锁,因此每个DDL都需要以新的LOCK语句开头。如果你想使用它,我建议添加一个超时(正如Justin的评论中所建议的那样)。让我们在放弃之前等待一分钟。

SQL> lock table tab in exclusive mode WAIT 60;

虽然如果这是一个繁忙的数据库上的无人参与的脚本,我可能会用超过60秒的时间。只需将所有内容记录到假脱机文件中,稍后检查日志是否有错误。

除此类维护之外的任何内容可能都要求您先停顿数据库,否则只需根据具体情况处理争用。