ORA-00060: 等待资源时检测到死锁

30

我在托管Oracle 10g的AIX服务器上使用nohup并行运行一系列脚本。这些脚本是其他人编写的,旨在同时执行。所有脚本都在对表进行更新。我遇到了错误,

ORA-00060: deadlock detected while waiting for resource

我通过谷歌搜索发现,http://www.dba-oracle.com/t_deadly_perpetual_embrace_locks.htm

虽然这些脚本正在对同一个表进行并发更新,但它们正在使用不同的WHERE子句确定表中不重叠的记录进行更新。

那么这是否会导致错误?

无论在表的哪个位置执行更新,此错误是否会发生?

我应该始终避免在表上进行并发更新吗?

奇怪的是,在nohup.out日志中还发现了:PL/SQL successfully completed上述引用错误之后。

这是否意味着Oracle已从死锁中恢复,并成功完成了更新?还是我应该按顺序重新运行这些脚本?

4个回答

33

我最近遇到了类似的问题。原来数据库缺少外键索引,导致Oracle锁定了比所需更多的记录,在高并发环境下很快就会出现死锁。

这里有一篇非常好的文章,详细介绍了如何解决死锁问题,提供了很多有用的建议和细节:http://www.oratechinfo.co.uk/deadlocks.html#unindex_fk


16
你不仅可以在行锁上遇到死锁,例如查看此处。 脚本可能会争夺其他资源,例如索引块。
过去我曾通过以这样一种方式设计并行性来解决这个问题:不同的实例处理较不可能相互影响的工作负载部分;例如,对于大表的更新,我会使用类似于MOD(n, 10)的东西设置并行进程,而是使用TRUNC(n/10),这意味着每个并行进程将处理一组连续的数据。
当然,还有更好的方法来拆分并行作业,例如DBMS_PARALLEL_EXECUTE
不确定为什么会出现“PL / SQL成功完成”的情况,也许你的脚本正在处理异常?

5

我也遇到了这个问题。我不知道实际发生了什么技术细节。然而,在我的情况中,根本原因是在Oracle数据库中设置了级联删除,并且我的JPA/Hibernate代码也尝试执行级联删除调用。因此,我的建议是要确保您确切地知道正在发生的事情。


1
我正在测试一个函数,其中有多个UPDATE语句在IF-ELSE块中。
我正在测试所有可能的路径,因此每次在再次运行该函数之前,我都使用“手动”UPDATE语句将表重置为其先前的值。
我注意到问题会在那些UPDATE语句之后发生;
我在用于重置表的UPDATE语句之后添加了一个COMMIT;,这解决了问题。
所以,要小心,问题不是函数本身...

1
这是一个很有吸引力的建议,但我希望在我的PL/SQL脚本中稍后有回滚选项。如果我已经提交了,我就失去了这个可能性。 - osullic

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接