Hitachi

ノンストップデータベース HiRDB Version 10 構造型データベース機能


2.9.9 デッドロック

2つのトランザクションが2つ以上の資源の確保をめぐって互いに相手を待つ状態となり,そこから先へ処理が進まなくなることをデッドロックといいます。

詳細については,マニュアル「HiRDB UAP開発ガイド」の「デッドロックと回避策」を参照してください。

デッドロックの例を次に示します。

〈この項の構成〉

(1) ルートレコードを格納しているページ間のデッドロックの例

4V FMBまたはSD FMBのSDBデータベースでは,2つのトランザクションが複数のルートレコードに対して同時に逆順にアクセスした場合,デッドロックが発生するおそれがあります。次に示す場合にも同様にデッドロックが発生するおそれがあります。

複数のルートレコードを逆順にアクセスした場合のデッドロックの例を,次の図に示します。

図2‒92 ルートレコードを格納しているページ間のデッドロックの例

[図データ]

[説明]
  1. 参照トランザクションがルートレコードAの格納ページにSRモードで排他を掛けて,レコードを参照します。

  2. 更新トランザクションがルートレコードBの格納ページにEXモードで排他を掛けて,レコードを更新します。

  3. 参照トランザクションがルートレコードBの格納ページにSRモードで排他を掛けようとしますが,更新トランザクションがEXモードで排他を掛けているため,ページの排他解除待ちとなります。

  4. 更新トランザクションがルートレコードAの格納ページにEXモードで排他を掛けようとしますが,参照トランザクションがSRモードで排他を掛けているため,ページの排他解除待ちとなり,デッドロックが検知されます。

ここでは,同一のレコード型内の複数のルートレコードに対する例を挙げましたが,レコード型が異なる複数のルートレコードを逆順にアクセスした場合にもデッドロックが発生するおそれがあります。

(2) 子レコードを格納しているページ間のデッドロックの例【4V AFM,SD FMB】

4V AFMのSDBデータベースでは,2つのトランザクションが複数のデータベースキー値のレコードを同時に逆順にアクセスした場合,デッドロックが発生するおそれがあります。

SD FMBのSDBデータベースでは,二次インデクスを使用して子レコードを検索する場合,子レコードを逆順にアクセスすると,子レコード格納ページ間で,デッドロックが発生するおそれがあります。

デッドロックの例を次の図に示します。

図2‒93 子レコードを格納しているページ間のデッドロックの例

[図データ]

[説明]

上記の図は,複数のデータベースキー値のレコードを逆順にアクセスした場合のデッドロックの例です。

  1. 参照トランザクションがデータベースキー値A(1)のレコードの格納ページにSRモードで排他を掛けて,レコードを参照します。

  2. 更新トランザクションがデータベースキー値A(2)のレコードの格納ページにEXモードで排他を掛けて,レコードを更新します。

  3. 参照トランザクションがデータベースキー値A(2)のレコードの格納ページにSRモードで排他を掛けようとしますが,更新トランザクションがEXモードで排他を掛けているため,ページの排他解除待ちとなります。

  4. 更新トランザクションがデータベースキー値A(1)のレコードの格納ページにEXモードで排他を掛けようとしますが,参照トランザクションがSRモードで排他を掛けているため,ページの排他解除待ちとなり,デッドロックが検知されます。

ここでは,同一のレコード型内の複数のデータベースキー値に対する例を挙げましたが,レコード型が異なる複数のデータベースキー値のレコードを逆順にアクセスした場合もデッドロックが発生するおそれがあります。

なお,4V AFMのSDBデータベースのレコードの格納時には,格納位置を決めるために発生する検索の方向を指定する検索コードに従って子レコードの挿入位置を検索します。HiRDB/SDは指定された検索コードによってレコード間をNEXT方向またはPRIOR方向に,子レコードが格納されているページに順次アクセスする場合があります。このように直接子レコードを操作しなくても,上記のデッドロックが発生するおそれがあるため,検索方向にも注意してください。

(3) 仮想ルートレコードを格納しているページと子レコードを格納しているページ間のデッドロックの例【4V AFM】

4V AFMのSDBデータベースに対するアクセスでは,HiRDB/SDが内部的に仮想ルートレコードにアクセスすることがあるため,仮想ルートレコードを格納しているページと子レコードを格納しているページとの間でデッドロックが発生するおそれがあります。デッドロックの例を次の図に示します。

図2‒94 仮想ルートレコードを格納しているページと子レコードを格納しているページ間のデッドロックの例

[図データ]

[説明]

上記の図は,仮想ルートレコードを格納しているページと子レコードを格納しているページ間のデッドロックの例です。

  1. トランザクション1が,データベースキー値A(1)を参照するため,仮想ルートレコードの格納ページにSRモードで排他を掛けます。

  2. トランザクション1が,データベースキー値A(1)を参照するため,子レコードの格納ページにPUモードで排他を掛けて,子レコードを参照します。

  3. トランザクション2が,データベースキー値A(1)を参照するため,仮想ルートレコードの格納ページにSRモードで排他を掛けます。

  4. トランザクション1が,データベースキー値A(1)を削除するため,仮想ルートレコードの格納ページにEXモードで排他を掛けようとしますが,トランザクション2がSRモードで排他を掛けているため,ページの排他解除待ちとなります。

  5. トランザクション2が,データベースキー値A(1)を参照するため,子レコードの格納ページにPUモードで排他を掛けようとしますが,トランザクション1がPUモードで排他を掛けているため,ページの排他解除待ちとなり,デッドロックが検知されます。

ここでは,レコードの削除とレコードの検索が競合した場合の例を挙げましたが,このほかにも次のSDBデータベースを操作するAPIの競合時にも同じようにデッドロックが発生するおそれがあります。

また,異なるレコード型の間(例えば,4V FMBのSDBデータベースのルートレコードを格納しているページと,4V AFMのSDBデータベースの子レコードを格納しているページの間)でも,同じようにデッドロックが発生するおそれがあります。

(4) ルートレコードを格納しているページと子レコードを格納しているページ間のデッドロックの例【4V FMB,SD FMB】

次のどちらかの条件で,ルートレコードの検索またはルートレコードの位置指示子の位置づけを実行すると,その後の子レコードの更新,格納,または削除の際,ルートレコード格納ページと子レコード格納ページとの間でデッドロックが発生するおそれがあります。

また,SD FMBのSDBデータベースでは,二次インデクスを使用して子レコードを検索する場合,子レコードを逆順にアクセスするときも,ルートレコード格納ページと子レコード格納ページ間で,デッドロックが発生するおそれがあります。

デッドロックの例を次の図に示します。

図2‒95 ルートレコードを格納しているページと子レコードを格納しているページ間のデッドロックの例

[図データ]

[説明]

上記の図は,ルートレコードを格納しているページと子レコードを格納しているページ間のデッドロックの例です。

  1. トランザクション1が,データベースキー値Aを参照するため,ルートレコードの格納ページにSRモードで排他を掛けて,ルートレコードを参照します。

  2. トランザクション1が,データベースキー値A(1)を参照するため,子レコードの格納ページにPUモードで排他を掛けて,子レコードを参照します。

  3. トランザクション2が,データベースキー値Aを参照するため,ルートレコードの格納ページにSRモードで排他を掛けて,ルートレコードを参照します。

  4. トランザクション2が,データベースキー値A(1)を参照するため,子レコードの格納ページにPUモードで排他を掛けようとしますが,トランザクション1がPUモードで排他を掛けているため,ページの排他解除待ちとなります。

  5. トランザクション1が,データベースキー値A(1)を削除するため,ルートレコードの格納ページにEXモードで排他を掛けようとしますが,トランザクション2がSRモードで排他を掛けているため,ページの排他解除待ちとなり,デッドロックが検知されます。

(5) 排他モード1の指定が異なる検索が混在するトランザクションと,ほかのトランザクションが同じレコードに対してアクセスした場合のデッドロックの例【4V FMB,4V AFM】

4V FMBまたは4V AFMのSDBデータベースでは,SDBデータベースを操作するAPIの,排他モード1の指定が異なる検索が混在するトランザクションと,ほかのトランザクションが同じレコードに対してアクセスした場合,デッドロックが発生するおそれがあります。デッドロックの例を次の図に示します。

図2‒96 排他モード1の指定が異なる検索が混在するトランザクションと,ほかのトランザクションが同じレコード(同じページ)に対してアクセスした場合の,デッドロックの例

[図データ]

[説明]

上記の図は,排他モード1の指定が異なる検索が混在するトランザクションと,ほかのトランザクションが同じレコード(同じページ)に対してアクセスした場合の,デッドロックの例です。

  1. トランザクション1(個別開始X)が,データベースキー値Aを参照するため,レコードの格納ページにSRモードで排他を掛けます。

  2. トランザクション1(個別開始X)が,個別終了を行います(個別終了処理では排他制御は行いません)。

  3. トランザクション2が,データベースキー値Aを参照するため,レコードの格納ページにPUモードで排他を掛けます。

  4. トランザクション2が,データベースキー値Aを更新するため,レコードの格納ページにEXモードで排他を掛けようとしますが,トランザクション1(個別開始X)がSRモードで排他を掛けているため,ページの排他解除待ちとなります。

  5. トランザクション1(個別開始Y)が,データベースキー値Aを参照するため,レコードの格納ページにPUモードで排他を掛けようとしますが,トランザクション2がPUモードで排他を掛けているため,ページの排他解除待ちとなり,デッドロックが検知されます。

ここでは,同じページに格納された同じレコードに対するアクセスが競合した場合の例を挙げましたが,このほかに次の場合にも,同じようにデッドロックが発生するおそれがあります。

(6) FOR UPDATEオペランドの指定の有無が異なる検索が混在するトランザクションと,ほかのトランザクションが同じレコードに対してアクセスした場合のデッドロックの例【SD FMB】

SD FMBのSDBデータベースでは,FOR UPDATEオペランドの指定の有無が異なる検索が混在するトランザクションと,ほかのトランザクションが,同じレコードに対してアクセスをすると,デッドロックが発生するおそれがあります。デッドロックの例を次の図に示します。

図2‒97 FOR UPDATEオペランドの指定の有無が異なる検索が混在するトランザクションと,ほかのトランザクションが同じレコード(同じページ)に対してアクセスした場合の,デッドロックの例

[図データ]

[説明]

上記の図は,FOR UPDATEオペランドの指定の有無が異なる検索が混在するトランザクションと,ほかのトランザクションが,同じレコード(同じページ)に対してアクセスした場合の,デッドロックの例です。

  1. トランザクション1が,参照目的(FOR UPDATEオペランドの指定なし)でルートレコードAを参照するため,レコードの格納ページにSRモードで排他を掛けます。

  2. トランザクション2が,更新目的(FOR UPDATEオペランドの指定あり)でルートレコードAを参照するため,レコードの格納ページにPUモードで排他を掛けます。

  3. トランザクション1が,更新目的(FOR UPDATEオペランドの指定あり)でルートレコードAを参照するため,レコードの格納ページにPUモードで排他を掛けようとしますが,トランザクション2がPUモードで排他を掛けているため,ページの排他解除待ちとなります。

  4. トランザクション2が,ルートレコードAを更新するため,レコードの格納ページにEXモードで排他を掛けようとしますが,トランザクション1がSRモードで排他を掛けているため,ページの排他解除待ちとなり,デッドロックが検知されます。

ここでは,同じページに格納された同じレコードに対するアクセスが競合した場合の例を挙げましたが,このほかに次の場合にも,同じようにデッドロックが発生するおそれがあります。

(7) レコード格納用RDエリア間のデッドロックの例【SD FMB】

SD FMBのSDBデータベースでは,「表2-38 同一レコード格納用RDエリアに対する,SDBデータベースへのアクセスの同時実行可否(SD FMBのSDBデータベースの場合)」で説明しているように,レコード格納用RDエリアの排他によって待ち状態になることがあります。そのため,レコード格納用RDエリアにPRモード,PUモード,またはEXモードで排他を掛けるトランザクションと,ほかのトランザクションが,複数のレコード格納用RDエリアに対して同時に逆順にアクセスした場合,デッドロックが発生するおそれがあります。デッドロックの例を次の図に示します。

図2‒98 レコード格納用RDエリア間のデッドロックの例

[図データ]

[説明]

上記の図は,複数のレコード格納用RDエリアに逆順にアクセスした場合の,レコード格納用RDエリア間のデッドロックの例です。

  1. トランザクション1(SD排他モード:exclusive,アクセス目的:retrieve)が,ルートレコードAを参照するため,レコード格納用RDエリア1にEXモードで排他を掛けます。

  2. トランザクション2(SD排他モード:shared,アクセス目的:retrieve)が,ルートレコードBを参照するため,レコード格納用RDエリア2にSRモードで排他を掛けます。

  3. トランザクション1(SD排他モード:exclusive,アクセス目的:retrieve)が,ルートレコードBを参照するため,レコード格納用RDエリア2にEXモードで排他を掛けようとしますが,トランザクション2がSRモードで排他を掛けているため,レコード格納用RDエリアの排他解除待ちとなります。

  4. トランザクション2(SD排他モード:shared,アクセス目的:retrieve)が,ルートレコードAを参照するため,レコード格納用RDエリア1にSRモードで排他を掛けようとしますが,トランザクション1がEXモードで排他を掛けているため,レコード格納用RD エリアの排他解除待ちとなり,デッドロックが検知されます。

(8) デッドロックプライオリティ値による排他制御

デッドロックが発生した場合,どのトランザクションをエラーとするかをデッドロックプライオリティ値で制御できます。

この機能を使用する場合,システム共通定義のpd_deadlock_priority_useオペランドにYを指定してください。クライアント環境定義などからプログラム単位にHiRDB/SDがデッドロック優先順位を決定します。

デッドロックプライオリティ値が小さい方が処理の優先度が高く,値が大きくなるほどエラーになってロールバックされる可能性が高くなります。値が同じときは,後発のトランザクションの方がエラーとなって暗黙的にロールバックされます。

なお,この機能を使用しない場合は,後発のトランザクションがエラーとなり,暗黙的にロールバックされます。

(9) デッドロックの回避策

デッドロックは排他の範囲を広くすることで発生頻度を低減できますが,同時実行性は低下します。排他の範囲を狭くすると同時実行性は向上しますが,デッドロックの発生率が増加します。

デッドロックを回避するために,例えば次のような対策があります。

デッドロックが発生する原因と対策を次の表に示します。

表2‒43 デッドロックが発生する原因と対策

排他資源

発生原因

対策

レコード型とレコード型

レコード型のアクセス順序の不定

回避方法

UAPのアクセス順序を統一する。

対処

デッドロック発生後にUAPを再実行する。

レコード格納用RDエリア(SD FMBのSDBデータベースの場合)

レコード格納用RDエリアのアクセス順序の不定

回避方法
  • UAPのアクセス順序を統一する。

  • SD排他モードの指定をsharedに変更する。

対処

デッドロック発生後にUAPを再実行する。

ページ

複数ページ

  • 4V FMBまたはSD FMBのSDBデータベースのルートレコードアクセス順序の不定

  • 4V AFMのSDBデータベースの同一データベースキー値へのアクセス順序の不定

回避方法(4V FMBまたは4V AFMのSDBデータベースの場合)
  • UAPのアクセス順序を統一する。

  • 排他自動解除機能を適用する。

  • 無排他検索機能を適用する。

回避方法(SD FMBのSDBデータベースの場合)
  • UAPのアクセス順序を統一する。

  • 排他自動解除機能を適用する。

  • 無排他検索機能を適用する。

対処

デッドロック発生後にUAPを再実行する。

子レコードの更新,格納,削除

回避方法(4V FMBのSDBデータベースの場合)

ルートレコードを検索する場合,SDBデータベースを操作するAPIの,排他モード1の指定を'O'(占有モード)にする。

回避方法(SD FMBのSDBデータベースの場合)

SDB用UAP環境定義のsubschemaオペランドの-pオプションを指定しない。

対処

デッドロック発生後にUAPを再実行する。

SD FMBのSDBデータベースの,二次インデクスを使用した子レコードの検索

回避方法
  • UAPのアクセス順序を統一する。

  • 無排他検索機能を適用する。

対処

デッドロック発生後にUAPを再実行する。

単一ページ※1

■4V FMBまたは4V AFMのSDBデータベースの場合

同一トランザクション内で,同一ページに対する検索を,次の順序で実行※2する。

  1. SDBデータベースを操作するAPIの排他モード1に'S'(共用モード)を指定する。

  2. SDBデータベースを操作するAPIの排他モード1に'E'(排他モード)を指定する。

回避方法
  • 排他自動解除機能を適用する。

  • 無排他検索機能を適用する。

  • SDBデータベースを操作するAPIの排他モード1の指定を'O'(占有モード)に変更する。

対処

デッドロック発生後にUAPを再実行する。

■SD FMBのSDBデータベースの場合

同一トランザクション内で,同一ページに対する検索を,次の順序で実行する。

  1. FOR UPDATEオペランドを指定しないで検索する。

  2. FOR UPDATEオペランドを指定して検索する。

回避方法
  • 排他自動解除機能を適用する。

  • FOR UPDATEオペランドを指定する。

  • 無排他検索機能を適用する。

対処

デッドロック発生後にUAPを再実行する。

注※1

複数ページでも,同様のデッドロックが発生することがあります。

注※2

1トランザクション中で複数の個別開始をすることで,実行できます。

デッドロックが発生すると,自動的にHiRDB/SDがデッドロックとなったトランザクションのどれかをエラーにしてロールバックさせます。デッドロックによって暗黙的にロールバックされたUAPは,ROLLBACK文,またはDISCONNECT文でトランザクションを終了させないと,SDBデータベースを操作するAPIを実行してもエラーとなります。また,OLTP環境でX/Openに従ったアプリケーションプログラムをクライアントとした場合に,実行したアプリケーションプログラムがデッドロックとなったときもトランザクションの終了が必要です。

なお,デッドロック発生時にデッドロック情報を出力したい場合,システム共通定義またはユニット制御情報定義のpd_lck_deadlock_infoオペランドにYを指定する必要があります。pd_lck_deadlock_infoオペランドについては,マニュアル「HiRDB システム定義」を参照してください。