2012-01-31 60 views
2

據我所知,涉及行鎖的死鎖的典型情況需要四條SQL語句。在一個事務中兩個更新行A和行B,然後在一個單獨的事務中另外兩個更新相同的行,並且需要相同的鎖,但以相反的順序。從Oracle跟蹤文件中查找涉及死鎖的所有語句?

事務1在事務2可以請求它之前獲取行A上的鎖,事務2在事務1可以獲得之前獲得行B上的鎖並且都不能獲得剩餘的所需鎖。一個或兩個事務必須回滾,所以另一個可以完成。

當我在死鎖後查看Oracle跟蹤文件時,它似乎只突出顯示兩個查詢。這似乎是每筆交易中最後一筆交易。

如何識別每個事務中涉及的其他語句,或者在Oracle跟蹤文件中是否缺少這些語句?

如果需要,我可以包含特定跟蹤文件的相關位。

回答

5

你是對的,在典型的行級死鎖中,你將有會話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的信息不在蹤跡中,它真的不容易獲得。

希望有所幫助。

+0

太好了 - 非常感謝。非常清楚。 – 2012-02-01 12:45:41