TP1/FS/Table Access 05-00以前では,レコードを追加または削除する場合,テーブル単位の排他を確保します。これをテーブル排他ありTAMテーブルアクセス機能といいます。テーブル単位の排他については,「4.2.6 TAMテーブルの排他制御」を参照してください。
TP1/FS/Table Access 05-01以降では,テーブル単位の排他を確保しないで,レコード単位の排他資源だけを確保して,TAMテーブルのレコードにアクセスできます。これをテーブル排他なしTAMテーブルアクセス機能といいます。
テーブル排他なしTAMテーブルアクセス機能を使用するときは,TAMテーブルのアクセス形態に,「テーブル排他を確保しない,追加・削除できる更新型」を指定します。アクセス形態は,TAMサービス定義のtamtableコマンド定義句またはtamaddコマンドで指定してください。tamtableコマンド定義句については,マニュアル「OpenTP1 システム定義」を,tamaddコマンドについてはマニュアル「OpenTP1 運用と操作」を参照してください。
同じOpenTP1システムで,テーブル排他なしTAMテーブルアクセス機能を使用するTAMテーブルと,テーブル排他ありTAMテーブルアクセス機能を使用するTAMテーブルを混在できます。
テーブル排他なしTAMテーブルアクセス機能を使用するときに,既存のTAMファイルをtamcreコマンドによって再作成する必要はありません。
dc_tam_open関数およびレコードにアクセスする関数(dc_tam_read,dc_tam_write,dc_tam_delete)で排他をします。COBOL言語のUAPの場合は,レコードへアクセスするプログラムで排他をします。
確保された排他は,TAMテーブルにアクセスしたトランザクションが終了したときに解放されます。
テーブル排他なしTAMテーブルアクセス機能でのTAMサービスの関数の排他指定と実際に排他される状態を次の表に示します。
表4-10 テーブル排他なしTAMテーブルアクセス機能でのTAMサービスの関数の排他指定と実際に排他される状態
TAMサービスの関数とフラグに指定した値 | テーブル排他 | レコード排他 | ||
---|---|---|---|---|
dc_tam_open関数 | テーブル排他 | 更新排他※1 | - | |
レコード排他 | - | - | ||
dc_tam_read関数 | 参照目的 | 排他なし | - | - |
排他あり | - | 参照排他 | ||
更新目的 | - | 更新排他 | ||
dc_tam_rewrite関数 | - | 更新排他※2 | ||
dc_tam_write関数 | - | 更新排他 | ||
dc_tam_delete関数 | - | 更新排他 |
テーブル排他ありTAMテーブルアクセス機能と,テーブル排他なしTAMテーブルアクセス機能の,レコード更新時の排他確保処理を次の図に示します。
図4-8 レコード更新時の排他確保処理
テーブル排他ありTAMテーブルアクセス機能とテーブル排他なしTAMテーブルアクセス機能のレコード追加時の排他確保処理を次の図に示します。
図4-9 レコード追加時の排他確保処理
このように,テーブル排他なしTAMテーブルアクセス機能とテーブル排他ありTAMテーブルアクセス機能では排他の確保処理が異なるため,トランザクション間でTAMテーブルへのアクセスが競合した場合の動作も異なります。テーブル排他ありTAMテーブルアクセス機能では,レコードを追加または削除するトランザクションが存在すると,ほかのトランザクションからは同じTAMテーブルに対してレコードを参照(排他あり),更新,追加,および削除できません。テーブル排他なしTAMテーブルアクセス機能では,アクセスするレコードが競合しなければ,同じTAMテーブルにアクセスできます。
テーブル排他ありTAMテーブルアクセス機能で,レコードアクセスが競合した場合の処理を次の図に示します。
図4-10 テーブル排他ありTAMテーブルアクセス機能でレコードアクセスが競合した場合の処理
テーブル排他なしTAMテーブルアクセス機能で,レコードアクセスが競合した場合の処理を次の図に示します。
図4-11 テーブル排他なしTAMテーブルアクセス機能でレコードアクセスが競合した場合の処理
テーブル排他なしTAMテーブルアクセス機能を使用する場合,次の点に注意してください。
dc_tam_open関数をテーブル排他指定(flagsにDCTAM_TBL_EXCLUSIVEを指定)で発行した場合,dc_tam_open関数内でテーブル排他を確保しますが,レコードにアクセスする関数(dc_tam_read,dc_tam_write,dc_tam_delete)との排他制御はしません。つまり,テーブル排他指定のdc_tam_open関数同士はテーブル排他で待ち合わせをしますが,テーブル排他指定のdc_tam_open関数とレコードにアクセスする関数の間では排他の待ち合わせをしません。
dc_tam_open関数の排他方式を次の図に示します。
図4-12 dc_tam_open関数の排他方式
レコードの削除をした場合,レコードを削除したトランザクションがコミットするまで,削除したレコードは空きレコードにはなりません。そのため,レコードを削除したトランザクションがコミットするまで,削除したレコードの領域は追加するレコードに割り当てられません。ただし,レコードを削除したトランザクションと同一トランザクション内で,キー値が同じレコードを追加する場合には,削除したレコードの領域が割り当てられます。
したがって,追加するレコード数分の空きレコードがない状態でレコードを追加する場合,追加するトランザクションと同じトランザクションで異なるキー値のレコードを削除しても,レコードの追加はDCTAMER_NOAREAでエラーリターンします。
レコードの追加がDCTAMER_NOAREAとなる例を次の図に示します。
図4-13 レコードの追加がDCTAMER_NOAREAとなる例
レコードの追加がDCTAMER_NOAREAとならないようにするには,追加するレコード数分の空きレコードを用意するか,またはレコードを削除したトランザクションをコミットしたあとでレコードを追加する必要があります。
追加するレコード数分の空きレコードを用意する場合の処理を次の図に示します。
図4-14 追加するレコード数分の空きレコードを用意する場合の処理
レコードを削除したトランザクションをコミットしたあとでレコードを追加する場合の処理を次の図に示します。
図4-15 レコードを削除したトランザクションをコミットしたあとでレコードを追加する場合の処理
tamaddコマンドによって,テーブル排他ありTAMテーブルアクセス機能を使用するTAMテーブルから,テーブル排他なしTAMテーブルアクセス機能を使用するTAMテーブルに変更したり,テーブル排他なしTAMテーブルアクセス機能を使用するTAMテーブルから,テーブル排他ありTAMテーブルアクセス機能を使用するTAMテーブルに変更したりすることはできません。変更した場合,tamaddコマンドは異常終了します。
テーブル排他ありTAMテーブルアクセス機能を使用するか,テーブル排他なしTAMテーブルアクセス機能を使用するかを変更する場合は,TAMサービス定義のtamtableコマンド定義句を変更してOpenTP1システムを正常開始するか,TAMサービス定義に登録しないでOpenTP1システムを正常開始してtamaddコマンドで新規登録して変更してください。
テーブル排他ありTAMテーブルアクセス機能を使用していたTAMテーブルを,テーブル排他なしTAMテーブルアクセス機能を使用するように変更する場合,デッドロックとなることがあります。詳細は,「4.2.11(1)(b) テーブル排他なしTAMテーブルアクセス機能を使用している場合」を参照してください。
dc_tam_status関数およびCBLDCTAM('INFO ')以外は,テーブル排他ありTAMテーブルアクセス機能と同じプログラムインタフェースを使用してTAMテーブルにアクセスできます。
なお,UAPは,リコンパイルまたは再リンケージが必要となることがあります。リコンパイルが必要な条件を表4-11に,再リンケージが必要な条件を表4-12に示します。
表4-11 リコンパイルが必要な条件
条件 | 必要な作業 | |||
---|---|---|---|---|
dc_tam_status使用 | あり | st_acs_type参照 | あり | アクセス形態の情報として,新定数DCTAM_STS_RECLCKが返却されるので,UAPを修正し,リコンパイルし直す必要があります。 |
なし | リコンパイルは不要です。 | |||
なし |
表4-12 再リンケージが必要な条件
条件 | 必要な作業 | |
---|---|---|
AP使用ライブラリ | アーカイブライブラリ | 再リンケージが必要です。 |
共用ライブラリ | 再リンケージは不要です。 |
dc_tam_status関数では,DC_TAMSTAT構造体のst_acs_typeにアクセス形態を返却します。このst_acs_typeに返却する値にDCTAM_STS_RECLCKを追加します。DCTAM_STS_RECLCKは,「テーブル排他を確保しない,追加・削除できる更新型」というアクセス形態を表し,テーブル排他なしTAMテーブルアクセス機能を使用するTAMテーブルであることを意味します。
dc_tam_status関数のそのほかの返却値および使用方法については,マニュアル「OpenTP1 プログラム作成リファレンス C言語編」を参照してください。
CBLDCTAM('INFO ')では,データ名Kにアクセス形態を返却します。このデータ名Kに返却する値にVALUE 'L'を追加します。VALUE 'L'は,「テーブル排他を確保しない,追加・削除できる更新型」というアクセス形態を表し,テーブル排他なしTAMテーブルアクセス機能を使用するTAMテーブルであることを意味します。CBLDCTAM('INFO ')のそのほかの返却値および使用方法については,マニュアル「OpenTP1 プログラム作成リファレンス COBOL言語編」を参照してください。
TAMサービス定義のtamtableコマンド定義句では,-aオプションにアクセス形態を指定します。テーブル排他なしTAMテーブルアクセス機能を使用する場合,この-aオプションのオプション引数にreclckを指定してください。reclckは,「テーブル排他を確保しない,追加・削除できる更新型」というアクセス形態を表し,テーブル排他なしTAMテーブルアクセス機能を使用するTAMテーブルであることを意味します。
tamtableコマンド定義句のそのほかのオプションおよび使用方法については,マニュアル「OpenTP1 システム定義」を参照してください。