SQL ServerにおけるREAD COMMITTEDとREPEATABLE READの隔離レベルの違い
SQL ServerにおけるREAD COMMITTEDとREPEATABLE READの隔離レベルの違い
SQL Serverには、トランザクションの分離レベルを制御する4つのオプションがあります。READ COMMITTEDとREPEATABLE READは、最もよく使用される2つのレベルです。
READ COMMITTEDでは、トランザクションは他のトランザクションがコミットしたデータのみを読み取ることができます。これは、他のトランザクションがまだ完了していない変更を見ることができないことを意味します。
REPEATABLE READでは、トランザクションは開始時点からコミットされたデータを読み取ることができます。これは、トランザクションの実行中に他のトランザクションがコミットした変更を見ることができることを意味します。
主な違い
項目 | READ COMMITTED | REPEATABLE READ |
---|---|---|
読み取れるデータ | コミットされたデータのみ | 開始時点からコミットされたデータ |
他のトランザクションの影響 | 未コミットされた変更は見えない | コミットされた変更が見える |
幻読 | あり | なし |
ダーティ読取り | なし | なし |
非再現性読取り | なし | あり |
幻読とは、あるトランザクションが別のトランザクションによって挿入されたデータを読み取れないことです。READ COMMITTEDでは、幻読が発生する可能性があります。
ダーティ読取りとは、あるトランザクションが別のトランザクションによってまだコミットされていない変更を読み取ることです。READ COMMITTEDとREPEATABLE READでは、ダーティ読取りは発生しません。
非再現性読取りとは、あるトランザクションが同じクエリを2回実行したときに、異なる結果を取得することです。REPEATABLE READでは、非再現性読取りが発生する可能性があります。
使用例
READ COMMITTEDは、データの整合性が重要ではない場合に使用されます。例えば、レポートを作成する場合などです。
REPEATABLE READは、データの整合性が重要な場合に使用されます。例えば、銀行取引の処理などです。
-- READ COMMITTED
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
BEGIN TRANSACTION;
UPDATE table1 SET value = 1 WHERE id = 1;
-- 別のトランザクションで
SELECT value FROM table1 WHERE id = 1;
-- 結果: 1
COMMIT TRANSACTION;
-- REPEATABLE READ
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
BEGIN TRANSACTION;
UPDATE table1 SET value = 2 WHERE id = 1;
-- 別のトランザクションで
SELECT value FROM table1 WHERE id = 1;
-- 結果: 2
COMMIT TRANSACTION;
このコードでは、最初のトランザクションはtable1
テーブルのvalue
列を1に更新します。2番目のトランザクションは、最初のトランザクションがコミットされる前に同じクエリを実行します。
READ COMMITTEDを使用している場合、2番目のトランザクションは最初のトランザクションによって更新された値(1)を読み取ります。これは、最初のトランザクションがコミットされているためです。
REPEATABLE READを使用している場合、2番目のトランザクションは最初のトランザクションが更新する前の値(null)を読み取ります。これは、2番目のトランザクションが開始された時点からコミットされたデータのみを読み取ることができるためです。
READ COMMITTEDとREPEATABLE READは、トランザクションの分離レベルを制御する2つのオプションです。それぞれ異なる特性があり、使用例も異なります。
どの分離レベルを使用するかは、アプリケーションの要件によって異なります。
サンプルコードの別の方法
-- READ COMMITTED
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
BEGIN TRANSACTION;
UPDATE table1 SET value = 1 WHERE id = 1;
-- 同じトランザクションで
SELECT value FROM table1 WHERE id = 1;
-- 結果: 1
COMMIT TRANSACTION;
-- REPEATABLE READ
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
BEGIN TRANSACTION;
UPDATE table1 SET value = 2 WHERE id = 1;
-- 同じトランザクションで
SELECT value FROM table1 WHERE id = 1;
-- 結果: 2
ROLLBACK TRANSACTION;
このコードでは、同じトランザクション内でUPDATE
とSELECT
クエリを実行しています。
READ COMMITTEDを使用している場合、SELECT
クエリはUPDATE
クエリによって更新された値(1)を読み取ります。これは、UPDATE
とSELECT
クエリが同じトランザクション内で実行されているためです。
READ COMMITTEDとREPEATABLE READには、上記以外にもいくつかの違いがあります。
- パフォーマンス: REPEATABLE READはREAD COMMITTEDよりもパフォーマンスが低下する可能性があります。これは、REPEATABLE READでは、コミットされていない変更を考慮する必要があるためです。
READ COMMITTEDとREPEATABLE READは、それぞれ異なる特性を持つ2つの分離レベルです。どの分離レベルを使用するかは、アプリケーションの要件によって異なります。
sql sql-server isolation-level