独立性水準では、あるトランザクションがアクセスしているデータに対し、他のトランザクションによる参照または更新を制御します。また、他のトランザクションが更新中の資源に対し、自トランザクションが参照または更新できるかを制御します。
独立性水準には以下の4種類があります。
独立性水準の初期値は、READ COMMITTEDになります。
独立性水準は、動作環境ファイルのDEFAULT_ISOLATIONまたはSET TRANSACTION文で変更可能です。
ただし、動作環境ファイルのR_LOCKの指定により、独立性水準は以下のようになります。
R_LOCK | DEFAULT_ISOLATION または | 独立性水準 |
---|---|---|
NO | REPEATABLE_READ | SERIALIZABLE |
上記以外 | SET TRANSACTION文の指定に従う | |
YES | SERIALIZABLE | REPEATABLE READ |
上記以外 | SET TRANSACTION文の指定に従う |
参考
SET TRANSACTION文の詳細は、“SQLリファレンス”を参照してください。
あるトランザクションの実行中に現れる可能性のある現象を以下に示します。
現象1)
トランザクションT1が行を更新する。T1がトランザクションを終了する前に、トランザクションT2がその行を読み込む。T1がROLLBACK文を実行した場合、T2は存在しなかった行を読むことになる。
現象2)
トランザクションT1が行を読み込む。トランザクションT2が、その行を更新または削除し、COMMIT文を実行する。T1がその行を再び読もうとした場合、更新した値を受け取るかまたはその行が削除されたことを知る。
現象3)
トランザクションT1が、ある探索条件を満たす行の集合を読み込む。トランザクションT2が、その探索条件を満たす行を追加する。T1が、同じ探索条件で再度行の集合を読み込んだ場合、最初とは異なった行の集合を得ることになる。
独立性水準 | 現象1) | 現象2) | 現象3) |
---|---|---|---|
SERIALIZABLE | 不可能 | 不可能 | 不可能 |
REPEATABLE READ | 不可能 | 不可能 | 可能 |
READ COMMITTED | 不可能 | 可能 | 可能 |
READ UNCOMMITTED | 可能 | 可能 | 可能 |
あるトランザクションが参照または更新した資源は、そのトランザクションが終了するまで、他のトランザクションから更新されないことが保証されます。
動作環境ファイルのパラメタR_LOCKで行単位の排他が指定されていない場合に有効です。
SERIALIZABLEの場合の排他処理を以下に示します。
図I.5 SERIALIZABLEの場合の排他
(1) 利用者AがCOMMIT(ROLLBACK)終了するまで資源を占有します。
(2) 利用者Bは、利用者Aが資源を占有しているため、待ち状態となります。
(3) 利用者AがCOMMIT(ROLLBACK)するので、利用者Aの資源は解放されます。
(4) 利用者Aが資源を解放したので、利用者Bの更新が実行されます。このとき、資源を占有します。
(5) 利用者BがCOMMIT(ROLLBACK)するので、利用者Bの資源は解放されます。
あるトランザクションが参照または更新した資源は、そのトランザクションが終了するまで、他のトランザクションからの更新がないことが保証されます。
動作環境ファイルのR_LOCKパラメタで行単位の排他が指定されている場合に有効です。
排他の単位が行単位でかつREPEATABLE READが指定された場合は、該当のトランザクションがアクセスしていない行は占有しないので、同一トランザクション内で、同一のSQL文をくり返し実行しても、異なる集合が検索される場合があります。
REPEATABLE READの場合の排他処理を以下に示します。
図I.6 REPEATABLE READの場合の排他
(1) 利用者Aは、COL1がAの行を参照します。トランザクションが終了するまでこの行の集合を占有します。
(2) 利用者Bは、利用者Aが参照した行に対しては更新することができませんが、INSERT文で行を追加することはできます。
(3) 利用者Aが、再びCOL1がAの行を参照します。このとき前回参照した行に加えて、利用者Bが追加した行も検索されます。
動作環境ファイルのパラメタR_LOCKで行単位の排他が指定しているか否かで行の見え方が異なる場合があります。次に行単位の排他を指定した場合と、指定しない場合について説明します。
以下のSQL文を実行した場合、表の1行に対応する更新前のデータと更新中のデータを2重に保持しているため、検索する行が更新途中であっても、排他待ちすることなく、更新が発生する前のコミット済みのデータを検索することができます。
単一行SELECT文
更新可能性句に、FOR READ ONLYを指定したカーソル、または更新可能性句を省略したカーソルのOPEN文
READ COMMITTED を指定して、かつ、行単位を指定している場合の排他処理を以下に示します。
図I.7 READ COMMITTED を指定して、かつ、行単位を指定している場合の排他
(1) 利用者AがCOL1>0の行を参照します。このとき、行は占有しません。
(2) 利用者Bは利用者Aが資源を参照中に更新を行うことができます。このとき、資源を占有します。データベースには更新前の行に加え、更新後の行が格納されます。
(3) 利用者Aは利用者Bが行を更新占有中であっても参照を完了させることができます。検索される行には、利用者Bが更新途中の結果は反映されません。
(4) 利用者Bの更新が終了しますが、行の占有は続きます。
(5) 利用者AがCOL1>0の行を参照します。このとき、利用者Bが更新占有中の行であっても参照することができます。
(6) 利用者Bがトランザクションを終了し、行を解放します。
(7) 利用者Aの参照が終了します。参照中に利用者BがCOMMITしたため、検索される行には利用者Bの更新結果が一部反映されます。
(8) 利用者AがCOL1>0の行を参照します。このとき、行は占有しません。
(9) 利用者Aの参照が終了します。このとき、検索される行には利用者Bの更新結果がすべて反映されます。
注意
以下のSQL文は、各行の読み込み時の最新のコミット済みデータを参照します。
単一行SELECT文
更新可能性句に、FOR READ ONLYを指定したカーソル、または更新可能性句を省略したカーソルのOPEN文
このため、上記のSQL文実行中に更新業務がコミットした場合、次のような現象が起こることがあります。
SQL文の検索結果に、ある行については更新業務が更新する前の行、別の行については更新業務が更新した後の行が含まれる場合があります。
SQL文の検索結果に、ある行の更新前後の行がともに含まれる場合や、いずれも含まれない場合があります。
また、更新トランザクションを実行する場合、ある行について検索してから更新や削除するまでの区間に、他のトランザクションが更新や削除を行ってコミットする可能性があります。このような場合、データの整合性を保証するために、更新トランザクションについて以下の対処を行ってください。
カーソルの更新可能性句にFOR UPDATEを指定する。
占有モード指定にSHARE LOCK、またはEXCLUSIVE LOCKを指定する。
上記対処を行わないと以下の現象になります。
他のトランザクションが更新した行を上書きにより更新してしまう場合がある。
他のトランザクションが削除した行についてUPDATE文:位置づけやDELETE文:位置づけを行うと、対象行が存在しないのでエラーになる。
他のトランザクションが削除した行についてUPDATE文:探索やDELETE文:探索を行うと、対象行が存在しないのでデータなしになる。
あるトランザクションが更新した資源は、そのトランザクションが終了するまで、他のトランザクションから更新されないことが保証されます。しかし、以下のいずれかのSQL文で参照した資源に対しては、他のトランザクションから更新される可能性があります。
単一行SELECT文
更新可能性句に、FOR READ ONLYを指定したカーソルのOPEN文
トランザクションアクセスモードが読込み専用モードのときのOPEN文
したがって、同一トランザクション内でも、テーブル参照ごとに内容が異なる場合があります。
READ COMMITTED を指定して、かつ、行単位を指定していない場合の排他処理を以下に示します。
図I.8 READ COMMITTED を指定して、かつ、行単位を指定していない場合の排他
(1) 利用者Aが参照しているため(参照1)、この参照が終了するまで資源を占有します。
(2) 利用者Aが資源を解放するまで、利用者Bは更新を行えず、待ち状態となります。
(3) 利用者Aが参照終了(参照1)し、資源を解放します。
(4) 利用者Aが資源を解放したので、利用者Bの更新が実行されます。このとき、資源を占有します。
(5) 利用者Bが資源を解放するまで利用者Aは更新(更新)を行えず、待ち状態となります。
(6) 利用者Bの更新が終了します。
(7) 利用者Bがトランザクションを終了し、資源を解放します。
(8) 利用者Bが資源を解放したので、利用者Aの更新(更新)が実行されます。このとき、資源を占有します。
(9) 利用者Aが更新終了(更新)しますが、資源の占有は続きます。
(10) 利用者Aが参照(参照2)を行います。このとき検索される行は、利用者Bが更新した行を含みます。
(11) 利用者Aが参照(参照2)を終了しますが、資源の占有は続きます。
(12) 利用者Aがトランザクションを終了します。これによって資源が解放されます。
あるトランザクションが参照した資源は、他のトランザクションの参照および更新をまったく制限しません。また他のトランザクションが更新した資源も、トランザクションの終了を待たずに参照することができます。トランザクションが更新した資源は、トランザクション終了まで他のトランザクションの参照および更新を待たせます。
READ UNCOMMITTEDの場合の排他処理を以下に示します。
図I.9 READ UNCOMMITTEDの場合の排他
(1) 利用者Bは、更新処理(更新1)のため、COMMIT(ROLLBACK)終了するまで資源を占有します。
(2) 利用者Aは、資源を占有しないため、利用者Bが資源を占有していても、待ち状態にならずに参照処理(参照1)を行います。
(3) 利用者Aは利用者Bが資源を解放するまで更新を行えず、待ち状態となります。
(4) 利用者BがCOMMIT(ROLLBACK)します。利用者Bの資源は解放されます。
(5) 利用者Bが資源を解放したので、利用者Aの更新が実行されます。このとき、実際に更新した資源を占有します。
(6) 利用者Aが参照(参照2)を行います。このとき検索される行は、利用者Bが更新した行を含みます。
(7) 利用者Bは利用者Aが資源を解放するまで更新を行えず、待ち状態となります。
(8) 利用者Aが参照(参照2)を終了しますが、資源の占有は続きます。
(9) 利用者AがCOMMIT(ROLLBACK)します。
(10) 利用者Aが資源を解放したので、利用者Bの更新(更新2)が実行されます。このとき、資源を占有します。
(11) 利用者BがCOMMIT(ROLLBACK)します。