分離レベルについて

JDBC ドライバーのダウンロード

トランザクションでは、あるトランザクションを他のトランザクションから分離する方法を定義する分離レベルが指定されます。 分離とは、さまざまなトランザクションによって行われたリソースまたはデータの変更を分けることです。 分離レベルは、ダーティ リードやファントム読み取りなど、許可されるコンカレンシー副作用に対して説明されるものです。

トランザクション分離レベルでは次の作用が制御されます。

  • データの読み取り時にロックを獲得するかどうか、要求されるロックの種類。

  • 読み取りロックの保持期間。

  • 別のトランザクションによって変更された行を参照している読み取り操作で、次のことを行うかどうか。

    • その行に対する排他ロックが解放されるまでブロックする。

    • ステートメントまたはトランザクションの開始時に存在していた行の、コミット済みのバージョンを取得する。

    • コミットされていないデータ変更を読み取る。

分離レベルの選択

トランザクション分離レベルを選択しても、データ変更を保護するために獲得したロックは影響を受けません。 トランザクションでは、それにより変更されるあらゆるデータ上の排他的ロックが常に取得されます。 そのロックは、そのトランザクションに設定されている分離レベルが何であれ、トランザクションが完了するまで保持されます。 読み取り操作の場合、トランザクション分離レベルによって主に、操作が他のトランザクションの作用から保護されるしくみが定義されます。

分離レベルを下げると、同時にデータにアクセスできるユーザーの数がそれだけ増えます。 ただし、コンカレンシー作用の数が増え、ダーティ リードが発生したり、更新機会を逃したりすることがあります。 反対に、分離レベルを上げると、ユーザーが遭遇するコンカレンシー作用の種類が減ります。 ただし、必要なシステム リソースの量が増え、あるトランザクションが別のトランザクションをブロックする可能性が高くなります。 適切な分離レベルの選択は、アプリケーションのデータ整合性の要件と各分離レベルのオーバーヘッドとのバランスによって決まります。

最も高い分離レベルであるシリアル化可能では、読み取り操作を何度繰り返しても、まったく同じデータをトランザクションは必ず取得します。 ただし、マルチユーザー システムで他のユーザーに影響を与える可能性があるロッキング レベルが使用されます。 最も低い分離レベルは READ UNCOMMITTED ですが、このレベルでは、他のトランザクションによって変更され、まだコミットされていないデータを取得する場合があります。 コンカレンシーのあらゆる副作用が READ UNCOMMITTED では生じる可能性がありますが、読み取りロックやバージョニングは発生しないため、オーバーヘッドはごくわずかです。

Remarks

次の表は、分離レベルごとのコンカレンシーの副作用を示しています。

Isolation Level ダーティ リード 反復不能読み取り ファントム
READ UNCOMMITTED はい はい はい
READ COMMITTED いいえ はい はい
REPEATABLE READ いいえ いいえ はい
スナップショット いいえ いいえ いいえ
シリアル化可能 いいえ いいえ いいえ

2 つのトランザクションが同じ行を取得するときに発生しうる更新機会の逸失を防ぐため、トランザクションは少なくとも反復可能読み取りの分離レベルで実行する必要があります。 そうすることでトランザクションでは後に、元々取得した値に基づいて行が更新されます。 2 つのトランザクションが、元の取得した値に基づかずに 1 つの UPDATE ステートメントを使用して行を更新する場合、既定の分離レベル READ COMMITTED では更新データの喪失が発生しません。

トランザクションの分離レベルを設定するには、SQLServerConnection クラスの setTransactionIsolation メソッドを使用できます。 このメソッドは、引数として int 値を受け取ります。この値は、次のように接続定数のいずれかに基づいています。

con.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);

SQL Server の新しいスナップショット分離レベルを使用するには、SQLServerConnection 定数のいずれかを使用できます。

con.setTransactionIsolation(SQLServerConnection.TRANSACTION_SNAPSHOT);

また、次のように使用することもできます。

con.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED + 4094);

SQL Server の分離レベルの詳細については、SQL Server オンライン ブックの「データベース エンジンにおける分離レベル」を参照してください。

関連項目

JDBC ドライバーを使用したトランザクションの実行
SET TRANSACTION ISOLATION LEVEL (Transact-SQL)