我有一系列重命名表ddl语句,我想在事务中运行。在此期间,还会有其他会话也将运行,这些会话可能会劫持上面用于重命名的表并导致资源争用/死锁。
是否有可能在Oracle中实现这一目标?了解每个ddl语句将在每次执行后提交,这将释放表以供其他会话劫持。在其他会话可以访问表之前,如何确保执行DDL语句的当前会话成功完成?
--LOCK TABLE a
RENAME tbl a to b
--possible contention as commit release the lock on tbl a
RENAME tbl b to c
RENAME tbl c to d
--commit
答案 0 :(得分:2)
Oracle中的DDL语句都是一个事务。每个DDL语句在数据字典中引起很少或很多变化,比如obj $。我不确定,但看看Oracle已经完成的主要工作,以确保锁定不是他们平台的早期版本的问题,我认为他们发现每个DDL语句提交更容易保持锁定时间短并避免会话内或执行DDL的会话之间的死锁。在某些情况下,您仍然可以感觉到Oracle内核在生产使用过程中无法锁定并创建许多对象,并且ORA-600会被抛到脑后。
作为一种解决方法,您可以使用几年前推出的数据模型版本。我没有工作经验,因为它对我的工作来说太受限制了,但你可以通过Google搜索基于版本的重新定义来找到更多相关信息。或者前往Oracle manual。它可能在您正在使用的Oracle许可版中不可用。
作为解决方法,您可以在正常运行时间内执行语句。但这通常会破坏会话,除非用户执行的代码自动恢复。请记住,每个对象都有一个ID和一个名称。更改名称可能不会更改ID,因此需要刷新对象的许多指针,从而导致ORA-4063或类似。据我所知,Oracle没有暂停/暂停会话。