分離レベルについて

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

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

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

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

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

  • 別のトランザクションによって変更された行を参照する読み取り操作かどうか:

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

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

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

分離レベルの選択

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

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

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

解説

次の表は、各分離レベルで許容される同時実行による副作用を示しています。

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

2 つのトランザクションが同じ行を取得するときに発生しうる更新機会の逸失を防ぐため、トランザクションは少なくとも反復可能読み取りの分離レベルで実行する必要があります。 そうすることでトランザクションでは後に、元々取得した値に基づいて行が更新されます。 2 つのトランザクションが単一の 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)