ページの先頭行へ戻る
Symfoware Server V10.0.0 アプリケーション開発ガイド(共通編)

1.1.7 排他制御

アプリケーションからデータベースへアクセスする場合には、トランザクション単位にSymfoware/RDBで排他制御を行います。

データベースの同一資源に対して、アプリケーションおよびRDBコマンドが同時に動作した場合のSymfoware/RDBの排他制御の詳細については、“付録D アプリケーションおよびRDBコマンド間の排他”を参照してください。

1.1.7.1 排他の属性と選択方法

排他の属性には、以下のものがあります。

以下に、排他の属性の指定方法と、排他の属性の各項目の概要を説明します。

排他の属性の指定方法

排他の属性を指定するには、以下の方法があります。

占有の資源

占有する対象の資源は、そのアプリケーションで使用する表のDSIおよびインデックスのDSIです。

占有の単位

占有制御によって資源を占有する単位には、行単位、ぺージ単位およびDSI単位があります。

行単位の占有の場合には、アプリケーションがアクセスするデータを含む行が占有の対象になります。ぺージ単位の占有の場合には、アプリケーションがアクセスするデータを含むぺージが占有の対象になります。DSI単位の占有の場合には、アプリケーションがアクセスするデータを含むDSIが占有の対象になります。占有単位を指定するには、以下の方法があります。

動作環境ファイルの実行パラメタDSO_LOCKおよびR_LOCKでの指定

占有単位は、動作環境ファイルの実行パラメタDSO_LOCKでDSO単位に指定するかまたは、R_LOCKで指定します。

動作環境ファイルの実行パラメタの指定と占有単位について以下に示します。

表1.2 動作環境ファイルの実行パラメタによる占有単位の選択方法

動作環境ファイル
の実行パラメタ

ページ指定あり

ページ指定なし

DSO_LOCK

指定したDSOの全DSIをぺージ単位で占有

指定したDSOの全DSIをDSI単位で占有

R_LOCK

行単位で占有

R_LOCKの値により、DSO_LOCKを指定できない場合があります。以下にDSO_LOCKとR_LOCKの関係を示します。

表1.3 DSO_LOCKとR_LOCKの関係

クライアント用の動作環境ファイルのR_LOCK

システム用の動作環境ファイルのR_LOCK

DSO_LOCKの指定

占有単位

NO

NO

指定可

DSO_LOCKの指定による

YES

指定可

DSO_LOCKの指定による

YES

NO

指定不可

行単位で占有(注)

YES

指定不可

行単位で占有(注)

省略

NO

指定可

DSO_LOCKの指定による

YES

指定不可

行単位で占有(注)

注) DSO_LOCKを指定した場合、CONNECT文実行時にエラーとなります。

Symfoware/RDBによる選択

動作環境ファイルでDSO_LOCKを指定せず、R_LOCKにNOを指定した場合は、Symfoware/RDBによって占有の単位が選択されます。

Symfoware/RDBは、SQL文ごとに、そのSQL文でアクセスするデータの範囲(ぺージ数)を算定します。その範囲(ぺージ数)の大きさに応じて、以下に示すように占有単位を選択しています。

表1.4 Symfoware/RDBによる占有単位の選択条件

占有単位

選択条件

ページ

アクセスするデータの範囲が小さい場合

DSI

アクセスするデータの範囲が大きい場合

たとえば、表を全件処理する場合には、表のデータを格納している全DSIに対してDSI単位の占有を選択します。また、SQL文の探索条件を解析し、アクセスするぺージが少ないと算定した場合には、ぺージ単位の占有を選択します。なお、アクセスするデータの量が少なくても、その範囲(ぺージ数)が大きい場合には、DSI単位の占有を選択します。

占有モード

データベースにアクセスする場合の占有モードには、共有モードと非共有モードの2種類があります。

共有モードの場合、ロックされたデータは、ほかのトランザクションからのデータ操作において、参照だけが許され更新操作はできません。一般に、データのロックを獲得中のトランザクションのコミットが行われるまで、ほかのトランザクションのデータの更新操作は、待ち状態となります。非共有モードの場合、ロックされたデータは、ほかのトランザクションでデータ操作することはできません。一般に、データのロックを獲得中のトランザクションのコミットが行われるまで、ほかのトランザクションの実行は、待ち状態となります。

占有モードを指定するには、以下の方法があります。

動作環境ファイルの実行パラメタDSO_LOCKでの指定

アプリケーションの動作環境ファイルの実行パラメタDSO_LOCKを指定すると、データ操作のSQL文を実行したとき、データおよびインデックスに対する占有モードを指定することができます。

データに対する占有

データに対する占有モードは、以下に示すように、DSO単位に指定します。

表1.5 動作環境ファイルの実行パラメタによる占有モードの指定

DSO_LOCKでの指定

占有モード

SHを指定した場合

共有モード

EXを指定した場合、または省略した場合

非共有モード

インデックスに対する占有

インデックスに対する占有モードは、以下に示すように、インデックスのDSO単位に指定します。

表1.6 動作環境ファイルの実行パラメタによるインデックスに対する占有モードの指定

DSO_LOCKでの指定

占有モード

SHを指定した場合

共有モード

EXを指定した場合、または省略した場合

非共有モード

Symfoware/RDBによる選択

動作環境ファイルでDSO_LOCKを指定しなかった場合は、Symfoware/RDBによって占有モードが選択されます。

データに対する占有

Symfoware/RDBは、アクセスするデータに対して、以下に示す条件で、SQL文ごとにデータに対する占有モードを選択します。

表1.7 Symfoware/RDBによる占有モードの選択

占有モード

選択条件

共有モード

データを参照する処理の部分の場合

非共有モード

データを更新する処理の部分の場合

データ検索を行う以下のSQL文については、アクセスするデータに対する占有モードは共有モードになります。また、これらのSQL文については、インデックスに対する更新が行われないので、インデックスに対するモードは共有モードになります。

  • OPEN文(ただし、カーソル宣言の更新可能性句にFOR UPDATEを指定したカーソルのOPEN文は、非共有モードで占有します。)

  • 単一行SELECT文

  • FETCH文

データの更新、削除および挿入を行う以下のSQL文については、処理(更新、削除および挿入)対象のデータに対する占有モードは、非共有モードになります。ただし、データ更新、削除および挿入を行うSQL文であっても、内部的に参照しか行わない部分に関しては、共有モードになります。

  • UPDATE文:探索

  • UPDATE文:位置づけ

  • DELETE文:探索

  • DELETE文:位置づけ

  • INSERT文

インデックスに対する占有

Symfoware/RDBは、SQL文の処理で使用するインデックスの更新の有無により、以下のように選択します。

表1.8 Symfoware/RDBによるインデックスに対する占有モードの選択

インデックスに対する占有モード

インデックス更新の有無

共有モード

インデックス更新なし

非共有モード

インデックス更新あり

データ更新を行う以下のSQL文については、更新対象の列に設定されているインデックスに対して更新が行われます。したがって、そのようなインデックスに対する占有モードは非共有モードになります。一方、更新対象でない列に設定されているインデックスに対しては、更新は行われないので、そのようなインデックスに対する占有モードは共有モードになります。

  • UPDATE文:探索

  • UPDATE文:位置づけ

データ削除および挿入を行う以下のSQL文については、更新対象の表に張られているインデックスに対して更新が行われます。したがって、そのようなインデックスに対する占有モードは非共有モードになります。

  • DELETE文:探索

  • DELETE文:位置づけ

  • INSERT文

動作環境ファイルの実行パラメタDEFAULT_ACCESS_MODEおよびDEFAULT_ISOLATION、またはSET TRANSACTION文での指定

動作環境ファイルの実行パラメタDEFAULT_ACCESS_MODEおよびDEFAULT_ISOLATION、またはSET TRANSACTION文での指定については、“1.1.3 トランザクションモード”を参照してください。

SQL文における占有モード指定での指定

SQL文に占有モード指定を指定することにより、SQL文が読み込んだ資源(データおよびインデックス)の占有モードと占有期間を柔軟に変更することができます。占有の単位は、アプリケーションの動作環境ファイルの実行パラメタR_LOCKがYESの場合、行単位となります。R_LOCKがNOの場合は、ページ単位またはDSI単位になります。

占有モード指定がある場合、SET TRANSACTION文で指定された内容とは無関係に動作します。また、アプリケーションの動作環境ファイルの実行パラメタDSO_LOCKは、指定できません。

占有モード指定と資源の占有について以下に示します。

表1.9 占有モード指定と資源の占有

占有モード指定

占有のしかたと占有期間

他のトランザクションとの
待ち関係

読込み水準

EXCLUSIVE
LOCK

非共有モードで、トランザクション終了まで資源を占有する。

当該トランザクションが終了するまで、同じ資源を参照/更新する他のトランザクションを待たせる。

COMMIT済みの行を読み込む。当該SQL文で読み込んだ行は、トランザクション終了まで他のトランザクションに更新されることがないため、一度読み込んだ行は、他のトランザクションによって更新されないことが保証される。

SHARE LOCK

共有モードで、トランザクション終了まで資源を占有する。

SQL文の実行後は、当該トランザクションが終了するまで、同じ資源を更新する他のトランザクションを待たせる。

FREE LOCK

共有モードで、SQL文終了(カーソルならば、OPEN文終了時)まで資源を占有する。

当該SQL文の実行中は、同じ資源を更新する他のトランザクションを待たせる。当該SQL文の実行が終了すると、同じ資源を更新する他のトランザクションを実行することができる。

COMMIT済みの行を読み込む。当該SQL文で読み込んだ行は、他のトランザクションに更新されることがあるため、同一トランザクションで再検索すると最新の結果を検索することができる。

NO LOCK

資源を占有しない。

当該SQL文を実行しても、他のトランザクションを待たせない。

他のトランザクションでCOMMITされていない更新中の行を読みことができる。

占有モード指定は、資源を読み込むときのモードです。読み込んだ資源の更新時には、占有モード指定での指定に関係なくEXCLUSIVE LOCKになります。

占有モード指定を指定したSQL文の待ち関係

占有モード指定を指定したSQL文が参照した資源に対する待ち関係を以下に示します。

更新した部分に関してはEXCLUSIVE LOCK指定がされたとみなして表を参照してください。

表1.10 占有モード指定と待ち関係

  

  

先行トランザクション

  

占有モード指定

EXCLUSIVE
LOCK

SHARE LOCK

FREE LOCK

NO LOCK

後続トランザクション

EXCLUSIVE LOCK

×

×

SHARE LOCK

×

FREE LOCK

×

NO LOCK

○:待つことなく動作する

△:先行トランザクションのSQL文の終了を待つ

×:先行トランザクションの終了を待つ

図1.11 ○:待つことなく動作する場合

図1.12 △:先行トランザクションのSQL文の終了を待つ場合

図1.13 ×:先行トランザクションの終了を待つ場合

カーソル宣言およびSET TRANSACTION文における指定とSQL文の占有モード指定における指定との対応関係

SQL文の占有モード指定を省略した場合、独立性水準、トランザクションアクセスモードおよび更新可能性句を組み合わせることによって、占有モード指定を指定したときと同等の資源の占有のしかたを設定できます。以下に、SET TRANSACTION文および更新可能性句での指定と、それに対応する占有モード指定を示します。

占有モード指定があるSQL文と、占有モード指定を省略したSQL文との待ち関係については、以下の表を利用して同等の占有モード指定を確認した後、“表1.10 占有モード指定と待ち関係”を参照してください。

  • 占有モード指定を省略したSQL文がINSERT文、UPDATE文:位置づけおよびDELETE文:位置づけの場合

    SET TRANSACTION文における指定

    対応する占有モード指定

    独立性水準

    トランザクション
    アクセスモード

    SERIALIZABLE
    REPEATABLE READ
    READ COMMITTED
    READ UNCOMMITTED

    READ WRITE

    EXCLUSIVE LOCK

  • 占有モード指定を省略したSQL文がUPDATE文:探索およびDELETE文:探索の場合

    SET TRANSACTION文における指定

    対応する占有モード指定

    独立性水準

    トランザクション
    アクセスモード

    SERIALIZABLE
    REPEATABLE READ
    READ COMMITTED

    READ WRITE

    SHARE LOCK
    (更新対象行を検索するとき)
    EXCLUSIVE LOCK
    (更新対象行を更新するとき)

    READ UNCOMMITTED

    NO LOCK
    (更新対象行を検索するとき)
    EXCLUSIVE LOCK
    (更新対象行を更新するとき)

ただし、クライアント用の動作環境ファイルの実行パラメタUSQL_LOCKにEXを指定した場合は、更新対象行を検索するときから、EXCLUSIVE LOCKで資源を占有します。

  • 占有モード指定を省略したSQL文が、単一行SELECT文の場合

    SET TRANSACTION文における指定

    対応する占有モード指定

    独立性水準

    トランザクション
    アクセスモード

    SERIALIZABLE
    REPEATABLE READ

    READ ONLY
    READ WRITE

    SHARE LOCK

    READ COMMITTED

    READ ONLY
    READ WRITE

    FREE LOCK

    READ UNCOMMITTED

    READ ONLY
    READ WRITE

    NO LOCK


  • 占有モード指定を省略したSQL文が、カーソル宣言の場合

    SET TRANSACTION文における指定

    カーソル宣言の
    更新可能性句

    対応する占有モード指定

    独立性水準

    トランザクション
    アクセスモード

    SERIALIZABLE
    REPEATABLE READ

    READ ONLY

    FOR READ ONLY または
    省略

    SHARE LOCK

    READ WRITE

    FOR UPDATE

    EXCLUSIVE LOCK

    FOR READ ONLY または
    省略

    SHARE LOCK

    READ COMMITTED

    READ ONLY

    FOR READ ONLY または
    省略

    FREE LOCK

    READ WRITE

    FOR UPDATE

    EXCLUSIVE LOCK

    FOR READ ONLY

    FREE LOCK

    省略

    SHARE LOCK

    READ UNCOMMITTED

    READ ONLY

    FOR READ ONLY または
    省略

    NO LOCK

    READ WRITE

    FOR UPDATE

    EXCLUSIVE LOCK

    FOR READ ONLY または
    省略

    NO LOCK

SQL文単位の排他制御の例

SET TRANSACTION文によりトランザクションモードを変更する場合、一度トランザクションを終了させる必要があります。しかし、SQL文に占有モード指定を指定することにより、トランザクションを終了することなく、SQL文が読み込んだデータベース資源の占有状態を変更することができます。以下に、デッドロック抑止を目的とした占有モード指定の利用例を示します。

EXEC SQL SELECT * FROM  T1                                  …… (1)
          WHERE C1 = :H1
          WITH OPTION LOCK_MODE(EXCLUSIVE LOCK);
EXEC SQL UPDATE T1 …… (2) SET C2 = :H2 WHERE C1 = :H1; EXEC SQL COMMIT WORK; …… (3)

(1) デッドロック抑止を目的として、単一行SELECT文にEXCLUSIVE LOCKを指定します。参照時から資源を非共有モードで占有します。

(2) 単一行SELECT文によって位置づけられた行の列を更新します。

(3) COMMIT文によりトランザクションを終了します。

SQL文での占有モード指定の使用例

アプリケーションを多重実行する場合、更新処理があると非共有モードで資源を占有する必要があります。このため、他のアプリケーションが先に資源を占有している場合、そのアプリケーションのトランザクションが終了するまで、後続のアプリケーションは処理を待たされます。しかし、同一のレコードを同時に更新することがなければ、排他なしで参照し、実際に更新するレコードのみ排他制御を行えばよいので、システム全体の処理スピードを向上できます。

お互い同一のレコードを同時に更新しない場合は、レコード位置づけ処理において他のアプリケーションのトランザクションを待たないように、カーソル宣言の占有モード指定にNO LOCKを指定します。

図1.14 SQL文での占有モード指定

占有待ちの有無

トランザクション間で資源(行、ページ、DSI)に対して競合が発生した場合、その時点で占有待ちに入る(資源が解放されるまで待つ)場合と、アプリケーションに復帰する場合があります。

Symfoware/RDBによる選択

占有待ちを行います。

動作環境ファイルの実行パラメタでの選択方法

アプリケーションの動作環境ファイルの実行パラメタISOLATION_WAITで、以下に示すように指定します。

表1.11 動作環境ファイルの実行パラメタでの占有待ちの有無の選択方法

占有待ちの有無

選択方法

占有待ちになる

WAITを指定した場合、または省略した場合

アプリケーションに復帰する

REJECTを指定した場合

排他制御に関するパラメタの相互関係

排他制御に関する各パラメタの指定と、占有の単位および占有のふるまいについて、以下に示します。

表1.12 排他制御に関するパラメタの相互関係

R_LOCKの値

DSO_LOCK
の指定

SET TRANSACTION文の指定

占有モード指定の指定

占有のふるまい

占有の単位

YES

×

占有モード指定での指定に従う

行単位

-

SET TRANSACTION文の独立性水準に従う。ただし、独立性水準にSERIALIZABLEを指定した場合は、REPEATABLE READになる

-

占有モード指定での指定に従う

-

独立性水準は、REPEATABLE READになる

NO

×

×

独立性水準は、SERIALIZABLEになる

DSO_LOCKの指定に従う

-

占有モード指定での指定に従う

Symfoware/RDBによって自動的に決定される

-

SET TRANSACTION文の独立性水準に従う。ただし、独立性水準にREPEATABLE READを指定した場合は、SERIALIZABLEになる

-

占有モード指定での指定に従う

-

独立性水準は、SERIALIZABLEになる

○ : 指定可能

× : 指定できません

- : 指定を省略