2.9.9 コミットしていない削除データの排他制御
SDBデータベースを操作するAPIまたはDML(FETCH,FIND,またはFETCHDB ALL)で,4V FMBまたはSD FMBのSDBデータベースのルートレコードを検索する際に,SDBデータベースを操作するAPIまたはDML(ERASE)でルートレコードを削除するほかのトランザクションと競合する場合,シーケンシャルインデクス上で削除ルートレコードのインデクスキーを読み飛ばします。そのため,通常は削除中のルートレコードを検索することはできません。
しかし,ルートレコードを削除したトランザクションがロールバックした場合,そのルートレコードの内容が回復されるため,検索トランザクションでは,結果的にそのルートレコードを読み飛ばしたことになります。
この問題は,検索トランザクションで削除中のルートレコードのインデクスキーを参照したときに,ルートレコード格納ページ(コミットしていない削除データ)に排他を掛けることで回避できます。
(1) 適用基準
次の場合に,コミットしていない削除データに排他を掛けることを推奨します。それ以外の場合は,コミットしていない削除データに排他を掛けない運用を推奨します。
-
4V FMBまたはSD FMBのSDBデータベースに対して,次のSDBデータベースを操作するAPIまたはDMLを同時実行する可能性があり,検索トランザクションで削除中のルートレコードを読み飛ばすことができない業務がある場合
-
ルートレコードを削除対象とするレコードの削除(ERASE)
-
レコードの検索(FETCH),位置指示子の位置づけ(FIND),または複数レコードの検索(FETCHDB ALL)
-
(2) 指定方法
システム共通定義のpd_lock_uncommited_delete_dataオペランドにWAITを指定すると,コミットしていない削除データに排他を掛けることができます。詳細については,マニュアル「HiRDB Version 9 システム定義」のpd_lock_uncommited_delete_dataオペランドの説明を参照してください。pd_lock_uncommited_delete_dataオペランドの説明を参照する際の注意点を次に示します。
-
「DELETE文」を「SDBデータベースを操作するAPI(ERASE)によるルートレコードの削除」,または「DML(ERASE)によるルートレコードの削除」に読み替えてください。
-
「UPDATE文」に関する説明は無視してください。
-
このオペランドの指定に関係なく,「一意性制約」に関しては次のとおりに動作します。
-
同一キーを持つ,4V FMBまたはSD FMBのSDBデータベースのルートレコードのインデクスキーエントリが見つかった場合,そのインデクスキーを操作している相手トランザクションが未決着状態で,ロールバックする可能性があったとしても,排他制御でのチェックをしないでエラーとなります。
-
なお,HiRDB/SDが内部的に発行する,4V AFMのSDBデータベースの仮想ルートレコードの検索では,このオペランドの指定値に関係なく,WAITが指定されたものとして動作します。このオペランドにNOWAIT(省略値)を指定して4V AFMのSDBデータベースを操作する場合,マニュアル「HiRDB Version 9 システム定義」のpd_lock_uncommited_delete_dataオペランドの説明に記載されているHiRDBファイルの使用可能サイズの制限はありません。
(3) コミットしていない削除データに排他を掛けた場合の効果
コミットしていない削除データに排他を掛けた場合の効果を次に示します。
-
4V FMBまたはSD FMBのSDBデータベースのルートレコードを検索中に,コミットする前の削除データを検知した場合,検索トランザクションは,削除トランザクションのコミットまたはロールバックの決着を待ってから検索処理を行います。これによって,削除トランザクションでロールバックが発生した場合でも,検索トランザクションからの検索読み飛ばしを防止します。
(4) インデクス検索時の排他制御
システム共通定義のpd_lock_uncommited_delete_dataオペランドにWAITを指定した場合,インデクス検索時に削除中または削除済みのレコードを格納していたページにも排他を掛けます。
pd_lock_uncommited_delete_dataオペランドにWAITを指定した場合と,NOWAIT(省略値)を指定した場合のインデクス検索の動作の違いを次の図に示します。
- 注※1
-
削除中または削除済みのレコードのインデクスキーも含みます。
- 注※2
-
排他制御モードについては,次の個所を参照してください。
- 注※3
-
削除中または削除済みのレコードのインデクスキーは含みません。
- 注※4
-
排他待ちが発生した場合に削除されていることがあります。
(5) 注意事項
(a) インデクスの残存エントリ
SDBデータベースを操作するAPIまたはDMLで次のどちらかの操作を行った場合,インデクスキーエントリは削除されません。残存エントリとしてインデクス内に残ります。
-
レコードの削除(ERASE)によってインデクスが定義されたレコード型のレコードを削除した場合(この場合,削除レコードのインデクスキーエントリが残存エントリとして残ります)
-
レコードの削除(ERASE)またはレコードの一括削除によって仮想ルートレコード配下の子レコードをすべて削除した場合(この場合,仮想ルートレコードのシステム用構成要素がX'0000'のインデクスキーエントリが残存エントリとして残ります)
インデクスの残存エントリの注意事項については,マニュアル「HiRDB Version 9 UAP開発ガイド」の「コミットしていない削除データの排他制御」のインデクスの残存エントリの注意事項を参照してください。インデクスの残存エントリの注意事項を参照する際の注意点を次に示します。
-
残存エントリの発生条件については,前述したとおりです。
-
インデクスキーの更新に関する説明は無視してください。
-
「pdrorg」を「pdsdbrogおよびpdsdblod」に読み替えてください。
-
回避策2はSDBデータベースには適用できないため,無視してください。
-
「表の残存エントリ」の説明は無視してください。