アプリケーションからデータベースへアクセスする場合には、トランザクション単位にSymfoware/RDBで排他制御を行います。
データベースの同一資源に対して、アプリケーションおよびRDBコマンドが同時に動作した場合のSymfoware/RDBの排他制御の詳細については、“付録D アプリケーションおよびRDBコマンド間の排他”を参照してください。
DSO定義でPRECEDENCE(1)が指定されたSEQUENTIAL構造の表の排他制御については、“1.1.12 PRECEDENCE(1)を指定したSEQUENTIAL構造の特徴と注意事項”を参照してください。
排他の属性を指定するには、以下の方法があります。
動作環境ファイルの実行パラメタによる指定
動作環境ファイルの実行パラメタによって設定できる属性は、以下のとおりです。
資源の占有モードおよび占有単位について指定します。指定されたDSO配下の全DSIに対する占有モードおよび占有単位となります。
占有待ちの有無について指定します。
占有単位について指定します。
トランザクションアクセスモードの初期値を指定します。
DEFAULT_ACCESS_MODEが指定された場合、プロセスで最初に実行されるSQL文の直前でSET TRANSACTION文が実行されたことになります。
独立性水準の初期値を指定します。
DEFAULT_ISOLATIONが指定された場合、プロセスで最初に実行されるSQL文の直前でSET TRANSACTION文が実行されたことになります。
各パラメタの記述形式については、“B.2 クライアント用の動作環境ファイル”を参照してください。
SET TRANSACTION文による指定
アプリケーション中にSET TRANSACTION文の独立性水準指定によって、占有の強さについて設定することができます。
参照
SET TRANSACTION文の詳細は、“SQLリファレンス”を参照してください。
Symfoware/RDBによる選択
動作環境ファイルの実行パラメタや、SET TRANSACTION文が指定されなかった場合、Symfoware/RDBがSQL文を解釈し、その結果をもとに選択します。
SQL文の占有モード指定による指定
SQL文に占有モード指定をすることにより、SQL文単位に読み込んだデータベース資源(データおよびインデックス)に対して占有モードを設定することができます。この機能を、イルシデーションロックといいます。
参照
占有モード指定の詳細は、“SQLリファレンス”を参照してください。
占有する対象の資源は、そのアプリケーションで使用する表のDSIおよびインデックスのDSIです。
占有制御によって資源を占有する単位には、行単位、ぺージ単位およびDSI単位があります。
行単位の占有の場合には、アプリケーションがアクセスするデータを含む行が占有の対象になります。このとき、データの参照または更新のための走査対象行も占有の範囲に含まれます。ぺージ単位の占有の場合には、アプリケーションがアクセスするデータを含むぺージが占有の対象になります。DSI単位の占有の場合には、アプリケーションがアクセスするデータを含むDSIが占有の対象になります。占有単位を指定するには、以下の方法があります。
動作環境ファイルの実行パラメタDSO_LOCKおよびR_LOCKでの指定
Symfoware/RDBによる選択
占有単位は、動作環境ファイルの実行パラメタDSO_LOCKでDSO単位に指定するかまたは、R_LOCKで指定します。
動作環境ファイルの実行パラメタの指定と占有単位について以下に示します。
動作環境ファイル | ページ指定あり | ページ指定なし |
---|---|---|
DSO_LOCK | 指定したDSOの全DSIをぺージ単位で占有 | 指定したDSOの全DSIをDSI単位で占有 |
R_LOCK | 行単位で占有 |
R_LOCKの値により、DSO_LOCKを指定できない場合があります。以下に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文実行時にエラーとなります。
動作環境ファイルでDSO_LOCKを指定せず、R_LOCKにNOを指定した場合は、Symfoware/RDBによって占有の単位が選択されます。
Symfoware/RDBは、SQL文ごとに、そのSQL文でアクセスするデータの範囲(ぺージ数)を算定します。その範囲(ぺージ数)の大きさに応じて、以下に示すように占有単位を選択しています。
占有単位 | 選択条件 |
---|---|
ページ | アクセスするデータの範囲が小さい場合 |
DSI | アクセスするデータの範囲が大きい場合 |
たとえば、表を全件処理する場合には、表のデータを格納している全DSIに対してDSI単位の占有を選択します。また、SQL文の探索条件を解析し、アクセスするぺージが少ないと算定した場合には、ぺージ単位の占有を選択します。なお、アクセスするデータの量が少なくても、その範囲(ぺージ数)が大きい場合には、DSI単位の占有を選択します。
データベースにアクセスする場合の占有モードには、共有モードと非共有モードの2種類があります。
共有モードの場合、ロックされたデータは、ほかのトランザクションからのデータ操作において、参照だけが許され更新操作はできません。一般に、データのロックを獲得中のトランザクションのコミットが行われるまで、ほかのトランザクションのデータの更新操作は、待ち状態となります。非共有モードの場合、ロックされたデータは、ほかのトランザクションでデータ操作することはできません。一般に、データのロックを獲得中のトランザクションのコミットが行われるまで、ほかのトランザクションの実行は、待ち状態となります。
占有モードを指定するには、以下の方法があります。
動作環境ファイルの実行パラメタDSO_LOCKでの指定
Symfoware/RDBによる選択
動作環境ファイルの実行パラメタDEFAULT_ACCESS_MODEおよびDEFAULT_ISOLATION、またはSET TRANSACTION文での指定
SQL文における占有モード指定での指定
アプリケーションの動作環境ファイルの実行パラメタDSO_LOCKを指定すると、データ操作のSQL文を実行したとき、データおよびインデックスに対する占有モードを指定することができます。
動作環境ファイルでDSO_LOCKを指定しなかった場合は、Symfoware/RDBによって占有モードが選択されます。
Symfoware/RDBは、アクセスするデータに対して、以下に示す条件で、SQL文ごとにデータに対する占有モードを選択します。
占有モード | 選択条件 |
---|---|
共有モード | データを参照する処理の部分の場合 |
非共有モード | データを更新する処理の部分の場合 |
データ検索を行う以下のSQL文については、アクセスするデータに対する占有モードは共有モードになります。また、これらのSQL文については、インデックスに対する更新が行われないので、インデックスに対するモードは共有モードになります。
OPEN文(ただし、カーソル宣言の更新可能性句にFOR UPDATEを指定したカーソルのOPEN文は、非共有モードで占有します。)
単一行SELECT文
FETCH文
データの更新、削除および挿入を行う以下のSQL文については、処理(更新、削除および挿入)対象のデータに対する占有モードは、非共有モードになります。ただし、データ更新、削除および挿入を行うSQL文であっても、内部的に参照しか行わない部分に関しては、共有モードになります。
UPDATE文:探索
UPDATE文:位置づけ
DELETE文:探索
DELETE文:位置づけ
INSERT文
Symfoware/RDBは、SQL文の処理で使用するインデックスの更新の有無により、以下のように選択します。
インデックスに対する占有モード | インデックス更新の有無 |
---|---|
共有モード | インデックス更新なし |
非共有モード | インデックス更新あり |
データ更新を行う以下のSQL文については、更新対象の列に設定されているインデックスに対して更新が行われます。したがって、そのようなインデックスに対する占有モードは非共有モードになります。一方、更新対象でない列に設定されているインデックスに対しては、更新は行われないので、そのようなインデックスに対する占有モードは共有モードになります。
UPDATE文:探索
UPDATE文:位置づけ
データ削除および挿入を行う以下のSQL文については、更新対象の表に張られているインデックスに対して更新が行われます。したがって、そのようなインデックスに対する占有モードは非共有モードになります。
DELETE文:探索
DELETE文:位置づけ
INSERT文
動作環境ファイルの実行パラメタDEFAULT_ACCESS_MODEおよびDEFAULT_ISOLATION、またはSET TRANSACTION文での指定については、“1.1.3 トランザクションモード”を参照してください。
SQL文に占有モード指定を指定することにより、SQL文が読み込んだ資源(データおよびインデックス)の占有モードと占有期間を柔軟に変更することができます。占有の単位は、アプリケーションの動作環境ファイルの実行パラメタR_LOCKがYESの場合、行単位となります。R_LOCKがNOの場合は、ページ単位またはDSI単位になります。
占有モード指定がある場合、SET TRANSACTION文で指定された内容とは無関係に動作します。また、アプリケーションの動作環境ファイルの実行パラメタDSO_LOCKは、指定できません。
占有モード指定と資源の占有について以下に示します。
占有モード指定 | 占有のしかたと占有期間 | 他のトランザクションとの | 読込み水準 |
---|---|---|---|
EXCLUSIVE | 非共有モードで、トランザクション終了まで資源を占有する。 | 当該トランザクションが終了するまで、同じ資源を参照/更新する他のトランザクションを待たせる。 | COMMIT済みの行を読み込む。当該SQL文で読み込んだ行は、トランザクション終了まで他のトランザクションに更新されることがないため、一度読み込んだ行は、他のトランザクションによって更新されないことが保証される。 |
SHARE LOCK | 共有モードで、トランザクション終了まで資源を占有する。 | SQL文の実行後は、当該トランザクションが終了するまで、同じ資源を更新する他のトランザクションを待たせる。 | |
FREE LOCK | 共有モードで、SQL文終了(カーソルならば、OPEN文終了時)まで資源を占有する。 | 当該SQL文の実行中は、同じ資源を更新する他のトランザクションを待たせる。当該SQL文の実行が終了すると、同じ資源を更新する他のトランザクションを実行することができる。 | COMMIT済みの行を読み込む。当該SQL文で読み込んだ行は、他のトランザクションに更新されることがあるため、同一トランザクションで再検索すると最新の結果を検索することができる。 |
NO LOCK | 資源を占有しない。 | 当該SQL文を実行しても、他のトランザクションを待たせない。 | 他のトランザクションでCOMMITされていない更新中の行を読みことができる。 |
占有モード指定は、資源を読み込むときのモードです。読み込んだ資源の更新時には、占有モード指定での指定に関係なくEXCLUSIVE LOCKになります。
占有モード指定を指定したSQL文が参照した資源に対する待ち関係を以下に示します。
更新した部分に関してはEXCLUSIVE LOCK指定がされたとみなして表を参照してください。
|
| 先行トランザクション | |||
---|---|---|---|---|---|
| 占有モード指定 | EXCLUSIVE | SHARE LOCK | FREE LOCK | NO LOCK |
後続トランザクション | EXCLUSIVE LOCK | × | × | △ | ○ |
SHARE LOCK | × | ○ | ○ | ○ | |
FREE LOCK | × | ○ | ○ | ○ | |
NO LOCK | ○ | ○ | ○ | ○ |
○:待つことなく動作する
△:先行トランザクションのSQL文の終了を待つ
×:先行トランザクションの終了を待つ
図1.11 ○:待つことなく動作する場合
図1.12 △:先行トランザクションのSQL文の終了を待つ場合
図1.13 ×:先行トランザクションの終了を待つ場合
SQL文の占有モード指定を省略した場合、独立性水準、トランザクションアクセスモードおよび更新可能性句を組み合わせることによって、占有モード指定を指定したときと同等の資源の占有のしかたを設定できます。以下に、SET TRANSACTION文および更新可能性句での指定と、それに対応する占有モード指定を示します。
占有モード指定があるSQL文と、占有モード指定を省略したSQL文との待ち関係については、以下の表を利用して同等の占有モード指定を確認した後、“表1.10 占有モード指定と待ち関係”を参照してください。
占有モード指定を省略したSQL文がINSERT文、UPDATE文:位置づけおよびDELETE文:位置づけの場合
SET TRANSACTION文における指定 | 対応する占有モード指定 | |
---|---|---|
独立性水準 | トランザクション | |
SERIALIZABLE | READ WRITE | EXCLUSIVE LOCK |
占有モード指定を省略したSQL文がUPDATE文:探索およびDELETE文:探索の場合
SET TRANSACTION文における指定 | 対応する占有モード指定 | |
---|---|---|
独立性水準 | トランザクション | |
SERIALIZABLE | READ WRITE | SHARE LOCK |
READ UNCOMMITTED | NO LOCK |
ただし、クライアント用の動作環境ファイルの実行パラメタUSQL_LOCKにEXを指定した場合は、更新対象行を検索するときから、EXCLUSIVE LOCKで資源を占有します。
占有モード指定を省略したSQL文が、単一行SELECT文の場合
SET TRANSACTION文における指定 | 対応する占有モード指定 | |
---|---|---|
独立性水準 | トランザクション | |
SERIALIZABLE | READ ONLY | SHARE LOCK |
READ COMMITTED | READ ONLY | FREE LOCK |
READ UNCOMMITTED | READ ONLY | NO LOCK |
占有モード指定を省略したSQL文が、カーソル宣言の場合
SET TRANSACTION文における指定 | カーソル宣言の | 対応する占有モード指定 | |
---|---|---|---|
独立性水準 | トランザクション | ||
SERIALIZABLE | 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 |
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文によりトランザクションを終了します。
アプリケーションを多重実行する場合、更新処理があると非共有モードで資源を占有する必要があります。このため、他のアプリケーションが先に資源を占有している場合、そのアプリケーションのトランザクションが終了するまで、後続のアプリケーションは処理を待たされます。しかし、同一のレコードを同時に更新することがなければ、排他なしで参照し、実際に更新するレコードのみ排他制御を行えばよいので、システム全体の処理スピードを向上できます。
お互い同一のレコードを同時に更新しない場合は、レコード位置づけ処理において他のアプリケーションのトランザクションを待たないように、カーソル宣言の占有モード指定にNO LOCKを指定します。
図1.14 SQL文での占有モード指定
トランザクション間で資源(行、ページ、DSI)に対して競合が発生した場合、その時点で占有待ちに入る(資源が解放されるまで待つ)場合と、アプリケーションに復帰する場合があります。
占有待ちを行います。
排他制御に関するパラメタの相互関係
排他制御に関する各パラメタの指定と、占有の単位および占有のふるまいについて、以下に示します。
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になる |
○ : 指定可能
× : 指定できません
- : 指定を省略