在解锁 oracle 上更改表约束
Posted
技术标签:
【中文标题】在解锁 oracle 上更改表约束【英文标题】:alter table constraint on unlock oracle 【发布时间】:2014-10-15 16:11:02 【问题描述】:我正在尝试编写一个脚本,由不了解 pl/sql 的客户执行,
我在 PL/sql 中执行了一堆事务来清理它们的环境,然后必须添加一些约束以防止这种情况再次发生,我在清理后自动提交,并希望通过添加来完成我的 PL 块这些限制
唯一的问题是我不能保证表在尝试向它们添加约束时不会被锁定,在 oracle 中是否需要等待解锁类型的命令?
谢谢你,oracle 新手,似乎找不到这个,我已经梳理了一些 API,但在时间敏感性方面,当我认为它看起来很漂亮时,证明很难找到数据库管理的常规问题
【问题讨论】:
我不确定我是否理解这个问题。你关心什么样的锁?其他一些会话同时在桌子上做 DDL?或者其他一些会话同时在桌子上做 DML?假设您至少使用 11.1,也许您想在会话 oracle-base.com/articles/11g/ddl-lock-timeout-11gr1.php 中设置DDL_LOCK_TIMEOUT
参数。
DDL 和 ddl_lock_timeout 似乎对我的目的很好,不同类型的解决方案,但看起来非零就足够了 :) 谢谢!
我会把它设置为合理的,比如 5 分钟,如果是交互式的话。除非您拥有数据仓库,否则您不应再在 OLTP 数据库上运行事务,但 5 分钟为您提供合理的时间让锁成功并成功终止会话。
【参考方案1】:
在执行任何 DDL 之前,在您的 pl/sql 块中,您应该通过 execute immedaite 调用:
LOCK TABLE <table_name> IN EXCLUSIVE MODE WAIT <n>;
等待的秒数在哪里。
但是请记住,即使您在第一个 ddl 之后获得了锁,它也会被释放,因为 DDL 会自动提交。因此无法保证 DDL 命令列表会像在一个事务中一样被一个接一个地执行。
【讨论】:
+1 指出您需要为每个 DDL 重新发布一个新的 LOCK【参考方案2】:命令是:
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 在 cmets 中所建议的那样)。让我们等一分钟再放弃。
SQL> lock table tab in exclusive mode WAIT 60;
虽然如果这是一个繁忙数据库上的无人值守脚本,我可能会使用超过 60 秒的时间。只需将所有内容记录到假脱机文件中,稍后检查日志是否有错误。
除了这种维护之外的任何事情都可能需要您先静默数据库,否则只需根据具体情况处理争用。
【讨论】:
向你打个招呼,好先生,我现在对锁定有了更多了解:)以上是关于在解锁 oracle 上更改表约束的主要内容,如果未能解决你的问题,请参考以下文章
iPad应用程序首先进入纵向模式,然后在解锁屏幕后进入横向模式,在锁定时处于横向模式