我想在同一张桌子上运行两个程序,一个使用出生日期,另一个更新从第三个表格中取得的名称和姓氏。
使用birthday更新age字段的那个在整个表中运行,更新名称和姓氏的那个只更新基于键的第三个表上显示的行。
所以我发起了两个并且陷入僵局!有没有办法确定其中任何一个的优先顺序?我读到了nowait
并跳过锁定更新但是,我将如何返回跳过的那些?
希望你能帮助我!!
答案 0 :(得分:0)
一种可能性是锁定您将立即更新的所有行。在单个更新语句中执行所有更新将完成此操作。或
select whatever from T where ... for update;
另一个解决方案是创建我称之为“关守”的表。这两个过程都需要在更新相关表之前以独占模式锁定Gatekeeper表。第二个过程将阻塞,直到第一次提交但不会死锁。在11g中,您可以创建一个没有分配空间的表。
一种变化是在Gatekeeper中插入一行。然后仅使用select for update锁定该行。然后你可以在其他情况下使用Gatekeeper。
答案 1 :(得分:0)
我猜你被锁定了,因为所有行的更新和一小组行的更新以不同的顺序访问了行。
前者使用完全扫描并首先到达Raw A,然后继续到其他行,最终尝试锁定B行。但是,另一个查询是从索引或连接驱动的,并且已经锁定了行B,并且当它发现它已被锁定时,它被关闭了。
所以,修复:首先,有一个需要不断修改的年龄列是一个非常糟糕的主意。也许这样做是为了允许对年龄进行索引,但是通过正确编写的查询,出生日期的索引可以让您快速找到相同的记录。您已经破坏了规范化规则,最终编写了一个死锁应用程序。希望你只是更新需要更新的行,而不是所有这些行 - 不管是什么 - 我的意思是,那只会是疯了。
最好的解决方案是摆脱那个设计缺陷。
不太好的解决方案是通过在不同时间运行查询或使用DBMS_Lock来消除查询冲突,以便其中只有一个可以随时运行。