我在托管oracle 10g的AIX服务器上有一系列并行运行的脚本作为nohup。这些脚本由其他人编写,旨在同时执行。所有脚本都在表上执行更新。我收到了错误,
ORA-00060:检测到死锁 等待资源
当我搜索谷歌时,我发现, http://www.dba-oracle.com/t_deadly_perpetual_embrace_locks.htm
即使脚本同时在同一个表上执行更新,它们也会对WHERE
子句确定的表的不同记录执行更新,而不会在它们之间重叠记录。
这会导致错误吗?。
无论在表上执行更新的位置如何,都会发生此错误吗?
我是否应该始终避免对表进行并发更新?。
奇怪的是我也在nohup.out日志中找到了
上述引用错误后PL/SQL successfully completed
。
这是否意味着oracle已从死锁中恢复并成功完成更新或是否应该按顺序重新运行这些脚本? 欢迎任何帮助。
提前致谢。
答案 0 :(得分:28)
我最近在遇到类似的问题。原来,数据库缺少外键索引。这导致Oracle锁定了多于所需的记录,这些记录在高并发期间很快导致死锁。
这是一篇很棒的文章,其中包含许多有关如何修复死锁的详细信息,建议和详细信息: http://www.oratechinfo.co.uk/deadlocks.html#unindex_fk
答案 1 :(得分:11)
你可以在不仅仅是行锁上获得死锁,例如:见this。脚本可能正在竞争其他资源,例如索引块。
我过去通过设计并行性来解决这个问题,不同的实例正在处理不太可能影响彼此接近的块的工作负载部分;例如,对于更大的表,而不是使用MOD(n,10)
之类的东西设置并行从属,我使用TRUNC(n/10)
,这意味着每个从属工作在一组连续的数据上。 / p>
当然,有更好的方法来分割并行工作,例如: DBMS_PARALLEL_EXECUTE
不确定为什么你的“PL / SQL成功完成”,也许你的脚本正在处理异常?
答案 2 :(得分:3)
我也遇到了这个问题。我不知道实际发生的事情的技术细节。但是,in my situation的根本原因是Oracle数据库中存在级联删除设置,而我的JPA / Hibernate代码也尝试执行级联删除调用。所以我的建议是确保你确切知道发生了什么。
答案 3 :(得分:1)
我正在测试一个在UPDATE
块内有多个IF-ELSE
语句的函数。
我正在测试所有可能的路径,因此在再次运行该函数之前,我每次都使用'manual'UPDATE
语句将表重置为以前的值。
我注意到该问题将在这些UPDATE
声明之后发生;
我在用来重置表的COMMIT;
语句之后添加了UPDATE
,从而解决了问题。
因此,请注意,问题不在于函数本身...