9

Oracle 10 以降のバージョンでは、同じテーブルの異なる行を同時に操作している場合でも、同じテーブルで更新と削除を行うとデッドロックが発生する可能性がありますか?

テーブルには 2 つの列で構成される主キーがあり、他のテーブルに関連付けられている/参照されている FK はありません。また、他のテーブルとの親子関係はありません

私が信じているのは、デッドロックは発生しないということですが、アプリケーションで問題に直面しています。

Oracle トレースの追加:

次のデッドロックは ORACLE エラーではありません。これは、アプリケーションの設計におけるユーザー エラーまたは不適切なアドホック SQL の発行によるデッドロックです。次の情報は、デッドロックの判別に役立つ場合があります。

Deadlock graph:
                       ---------Blocker(s)--------  ---------Waiter(s)---------
Resource Name          process session holds waits  process session holds waits
TX-0007003e-0081d6c3        45     790     X            104      20           X
TX-00080043-0085e6be       104      20     X             45     790           X

session 790: DID 0001-002D-000035F9     session 20: DID 0001-0068-000007F6
session 20: DID 0001-0068-000007F6      session 790: DID 0001-002D-000035F9

Rows waited on:
  Session 790: obj - rowid = 0000F0C8 - AAAPDIAAMAAAEfIAAA
  (dictionary objn - 61640, file - 12, block - 18376, slot - 0)
  Session 20: obj - rowid = 0000F0C8 - AAAPDIAAMAAAEfGAAA
  (dictionary objn - 61640, file - 12, block - 18374, slot - 0)

----- Information for the OTHER waiting sessions ----- Session 20:
  sid: 20 ser: 4225 audsid: 57496371 user: 72/RPT_TABLE
    flags: (0x45) USR/- flags_idl: (0x1) BSY/-/-/-/-/-
    flags2: (0x40009) -/-/INC
  pid: 104 O/S info: user: oracle, term: UNKNOWN, ospid: 20798
    image: oracle@caidb10p-node1
  client details:
    O/S info: user: gtsgen, term: unknown, ospid: 1234
    machine: caiapp08p-node0.nam.nsroot.net program: JDBC Thin Client
    application name: JDBC Thin Client, hash value=2546894660
  current SQL:
  delete from RPT_TABLE.TEMP_TABLE_T1 where TEMP_T1_ID=:1

----- End of information for the OTHER waiting sessions -----

Information for THIS session:

----- Current SQL Statement for this session (sql_id=bsaxpc2bdps9q) ----- UPDATE RPT_TABLE.TEMP_TABLE_T1 temp1 SET temp1.CLIENT_ID = (SELECT MIN(INVMAP.CLIENT_ID) FROM LI_REF.REF_CLIENT_MAP INVMAP WHERE INVMAP.F_CODE = :B2 AND INVMAP.AID = temp1.ID AND temp1.R_ID=:B1 )
----- PL/SQL Stack -----
----- PL/SQL Call Stack -----
  object      line  object
  handle    number  name
45887d750        24  procedure RPT_TABLE.T1_UPDATE_StoredProc  

6399ba188         1  anonymous block
4

2 に答える 2

10

デッドロック グラフで質問を更新できれば、それは有益な情報です。(アプリケーションがデッドロックに遭遇すると、Oracle は ORA-00060 を発生させ、トレース ファイルが user_dump_dest に書き込まれます。) トレース ファイルを調べると、「デッドロック グラフ」と呼ばれるセクションが見つかります。それを投稿し、デッドロックを引き起こしたステートメントとデッドロックに関係する他のステートメントも投稿できれば、いくつかの結論を導き出すことができます。(私が要求したすべての情報は、トレース ファイルで入手できます。)

Alessandro が述べたように、同じテーブル内の異なる行をロックしているセッションが、親子関係の子テーブルのインデックス付けされていない外部キーが原因でデッドロックする可能性があります。また、テーブルが親子関係の一部でなくても、同じテーブルの異なる行を更新する 2 つのセッションでデッドロックが発生する可能性があります。たとえば、テーブルに ITL エントリが不足している場合です。

再度、上記で要求された情報を投稿してください。デッドロックの根本原因を特定できると確信しています。

2012 年 7 月 30 日に追加 **

デッドロック トレース ファイルが提供されたので、次を追加します。まず、トレース ファイルの内容に基づいて、これはセッションがロックしようとしている行でオーバーラップ/衝突するための単純なデッドロックです。デッドロックが異なる行にあるという以前のコメントにもかかわらず、この特定のデッドロックは同じ行に対する行レベルのロックが原因であることをお伝えします。

ロックが保持されているモードが「X」(排他的) であり、ロックが待機されているモードが「X」であることをデッドロック グラフが示しているという事実は、これが単純な行レベルのロックであることを示しています。

この場合、SID 20 は「RPT_TABLE.TEMP_TABLE_T1 where TEMP_T1_ID=:1 からの削除」を実行しており、すでに行 ID AAAPDIAAMAAAEfIAAA をロックしています。

一方、SID 790 は "RPT_TABLE.T1_UPDATE_StoredProc" を実行していますが、既に行 ID AAAPDIAAMAAAEfGAAA のロックを保持しています。

トレース ファイルの「Rows Waited on」セクションから、SID 20 は SID 790 が保持している行で待機しており、SID 790 は SID 20 が保持している行で待機していることに注意してください。これは古典的なデッドロックです。

いくつかの追加情報:

  • エンキュー タイプは TX (デッドロック グラフを参照) であるため、インデックス化されていない外部キーが原因で、これは間違いなくロックではありません。インデックス化されていない FK が原因でロックしている場合、エンキュー タイプは TX ではなく TM になります。(TM エンキューが関係するケースが少なくとも 1 つあり、それはインデックスのない FK ではありません。したがって、TM エンキューが常にインデックスのない FK を意味すると仮定しないでください。)

  • ロックが待機されているモードは「X」(排他的) であるため、これは行レベルのロックです。待機モードが 'S' (共有) の場合、行レベルのロックではありません。むしろ、ITL の不足、または PK または UK の施行である可能性があります。

それが役立つことを願っています!

于 2012-07-27T18:45:26.793 に答える
9

アプリケーションに外部キーが含まれているかどうかはわかりませんが、おそらくロックの原因である可能性があります。もしそうなら、これらのリンクを見てください:

http://docs.oracle.com/cd/E11882_01/server.112/e16508/consist.htm#BABCAHDJ

http://docs.oracle.com/cd/E11882_01/server.112/e16508/datainte.htm#CNCPT1657

Oracle Databaseは、依存する外部キーに関連する親キーの同時実行制御を最大化します。ロックの動作は、外部キー列がインデックス化されているかどうかによって異なります。外部キーが索引付けされていない場合、おそらく子表がより頻繁にロックされ、デッドロックが発生し、並行性が低下します。このため、ほとんどの場合、外部キーにはインデックスを作成する必要があります。唯一の例外は、一致する一意または主キーが更新または削除されない場合です。

ロックと索引付けされていない外部キー

次の両方の条件が真の場合、データベースは子テーブルの完全なテーブル ロックを取得します。

子テーブルの外部キー列にインデックスが存在しません。

セッションは、親テーブルの主キーを変更 (たとえば、行の削除または主キー属性の変更) するか、行を親テーブルにマージします。親テーブルへの挿入では、子テーブルのテーブル ロックは取得されません。

これが当てはまらない場合は、それに関する詳細情報を提供してみてください。セッションによって保留/要求されたロックの種類について教えてください。また、システム テーブル V$LOCK、V$LOCKED_OBJECT、DBA_DDL_LOCKS、DBA_DML_LOCKS、または V$SESSION_WAIT を調べてください。

于 2012-07-27T17:52:20.323 に答える