11.18.3 共用表の操作
(1) 検索
共用表はすべてのバックエンドサーバから参照できるため,共用表を検索するために最適なバックエンドサーバをHiRDBが決定します。なお,共用表を更新すると全バックエンドサーバで排他が掛かるため,検索処理と更新処理とのデッドロックが発生することがあります。デッドロックを回避するために,共用表の検索時は次のようにすることをお勧めします。
-
排他オプションにWITHOUT LOCK,又はWITHOUT LOCK NOWAITを指定する
-
共用表を更新するために検索する場合,FOR UPDATE句を指定する
なお,共用表に対してIN EXCLUSIVE MODE指定でLOCK文を実行すると,対象の共用表と共用インデクスが格納されているRDエリアに排他を掛けます。検索する表がLOCK文の対象ではなくても,アクセスするRDエリアが同じであれば排他制御されます。そのため,WITHOUT LOCK NOWAITを指定していても,ほかのトランザクションがIN EXCLUSIVE MODE指定でLOCK文を実行している場合は,共用表にアクセスできません。そのため,IN EXCLUSIVE MODE指定のLOCK文実行中は共用表を検索できません。
HiRDBが決定するバックエンドサーバの割り当て規則については,「共用表を検索するバックエンドサーバの割り当て規則」を参照してください。
(2) 更新
共用表を更新する場合,LOCK文でIN EXCLUSIVE MODEを指定し,全バックエンドサーバの共用RDエリアに排他を掛けなければ実行できません。ただし,インデクスキー値を変更しないUPDATE文は,LOCK文を発行しないで実行できます。共用表及び共用インデクスの更新は,COMMIT文発行時にディスクに書き込まれます。
なお,ローカルバッファを使用して共用表を更新する場合は,LOCK文を発行して更新してください。LOCK文を発行しない更新をしていて,サーバプロセスが異常終了すると,アボートコードPhb3008が出力されます(ユニットが異常終了することがあります)。
(a) LOCK文を発行する更新
LOCK文を発行する更新の流れを次に示します。
-
IN EXCLUSIVE MODE指定でLOCK文を発行します。
このとき,共用表だけでなく,共用表が格納されている共用RDエリア及び共用インデクスが格納されている共用RDエリアにも排他が掛かります。参照専用バックエンドサーバの共用RDエリアのグローバルバッファは無効化されます。
-
共用表に対して,INSERT,UPDATE,又はDELETE文を実行します。
更新可能バックエンドサーバが更新情報をファイルに反映します。
LOCK文が解除されるまで共用RDエリアに排他が掛かるので,同じ共用RDエリアにある,別の共用表への操作は待ち状態になります。
-
LOCK文を解除します。
- 注意事項
-
-
LOCK文はUAPの最初に発行してください。LOCK文発行時,関連する共用RDエリア内の表に対して,自サーバプロセスでオープン中のカーソルがあると,LOCK文はエラーになります。
-
共用表を更新する手続き及びトリガを作成する場合,LOCK文を記述してください。ただし,手続き及びトリガからLOCK文を実行する場合はトランザクションの開始時点から排他が掛かりません。そのため,エラーになるおそれがあります。
-
全バックエンドサーバで共用表,共用表が格納されている共用RDエリア,及び共用インデクスが格納されている共用RDエリアに排他を掛けるため,該当するRDエリアの表又はインデクスにアクセスする業務があると,デッドロック,又はサーバ間のグローバルデッドロックが発生するおそれがあります。
-
共用表を更新するトランザクションの決着前に更新可能バックエンドサーバのユニットが異常終了して再開始しない場合に次のような検索をすると,排他タイムアウトエラーになります(KFPA11770-Iメッセージが出力されます)。
・別のユニットの参照専用バックエンドサーバで,更新対象の共用表又はその表に定義されているインデクスが格納されているRDエリア内の表を検索
-
(b) LOCK文を発行しない更新
LOCK文を発行しない場合,実行できるのはインデクスキー値の変更がないUPDATE文だけです。また,少量の変更の場合だけにしてください。
LOCK文を発行しない更新の流れを次に示します。
-
全バックエンドサーバの状態を同じにするため,更新情報を全バックエンドサーバに配布します。
-
更新可能バックエンドサーバが更新情報をデータベースに反映します。
参照専用バックエンドサーバでは,グローバルバッファ上で更新し,COMMIT文発行までファイルに反映しないで更新情報を保持します。トランザクションがロールバックした場合,グローバルバッファ上で回復します。
- 注意事項
-
-
参照専用バックエンドサーバで,グローバルバッファがすべて更新中,かつCOMMIT文未発行で空きページがない状態になった場合,トランザクションはロールバックします。このため,LOCK文を発行しない場合は大量のデータを更新しないでください。
-
全バックエンドサーバで更新行に排他を掛けるため,同時に該当する表にアクセスする業務があるとデッドロック,又はサーバ間のグローバルデッドロックが発生するおそれがあります。デッドロックを回避するため,UPDATE文で更新する行はトランザクションで1件だけにすることをお勧めします。
-
共用表を更新するトランザクションの決着前に更新可能バックエンドサーバのユニットが異常終了して再開始しない場合に次のような検索をすると,排他タイムアウトエラーになります(KFPA11770-Iメッセージが出力されます)。
・別のユニットの参照専用バックエンドサーバで,更新対象の共用表又はその表に定義されているインデクスが格納されているRDエリア内の表を検索
-