据我所知,涉及行锁的死锁的典型情况需要四条SQL语句。两个在一个事务中更新行A和行B,然后在另一个事务中另外两个更新相同的行,并且需要相同的锁,但顺序相反。
事务1在事务2请求锁之前获取行A上的锁,事务2在事务1获得行B上的锁之前获取行B上的锁,两个事务都无法获取剩余的所需锁。必须回滚一个或两个事务,这样另一个事务才能完成。
当我在死锁之后检查Oracle跟踪文件时,它似乎只突出显示了两个查询。这些似乎是每个事务中的最后一个。
如何识别每个事务中涉及的其他语句,或者Oracle跟踪文件中是否缺少这些语句?
如果需要,我可以包含特定跟踪文件的相关部分。
发布于 2012-02-01 04:02:19
你是对的,在一个典型的行级死锁中,你会让会话1执行sql_a来锁定行1,然后会话2将执行sql_b来锁定行2,然后会话1将执行sql_c来尝试锁定行2,但是会话2还没有提交,所以会话1开始等待。最后,会话2出现了,它发出sql_d,试图锁定第1行,但是,由于会话1持有该锁,它开始等待。三秒后,检测到死锁,其中一个会话将捕获ORA-00060,并写入跟踪文件。
在此方案中,跟踪文件将包含sql_c和sql_d,但不包含sql_a或sql_b。
问题是,信息真的无法在任何地方获得。假设您执行一个DML,如果一个事务不存在,它将启动一个事务,生成一系列撤消和重做操作,然后进行更改。但是,一旦发生这种情况,会话就不再与该SQL语句相关联。真的没有干净的方法可以回到过去找到这些信息。
另一方面,当死锁发生时,sql_c和sql_d是与这些会话相关联的语句,因此,很明显,Oracle可以识别它们,并将它们包含在跟踪文件中。
因此,您是对的,有关sql_a和sql_b的信息不在跟踪中,并且确实不容易获得。
希望这能有所帮助。
https://stackoverflow.com/questions/9084429
复制相似问题