トランザクションの隔離は、同時実行トランザクションがお互いの変更をどのように見るかに影響します。これはACID特性の重要な部分です。ANSI SQLには四つの基本的な隔離レベルがあります:
レベルの選択はアプリケーションの要件に依存します:
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; BEGIN; -- 今後のSELECTは「凍結」された値を見ることになります
「REPEATABLE READレベルはすべてのDBでファントムリードから保護することを保証しますか?」
いいえ。PostgreSQLや他のいくつかのDBMSでは、REPEATABLE READレベルはダーティリードと非再現可能なリードを防止しますが、ファントムリードから必ずしも保護するわけではありません。MySQL/InnoDBではREPEATABLE READは実質的にSERIALIZABLEですが、他のDBMSではそうではありません。
-- 1つのトランザクションでSELECT * FROM orders WHERE amount > 100を読み取る; -- 別のトランザクションでamount > 100の新しい値が挿入されてコミットされる -- 最初のトランザクションは再度SELECTした際に「ファントム」の行を見ることになります、隔離がSERIALIZABLEより低い場合
ストーリー
金融サービスがパフォーマンスのためにREAD COMMITTEDのみをブロック — ユーザーは他のプロセスによってすでに変更された金額を見て、残高に不一致が生じました。
ストーリー
ホテル予約システムで同じ部屋の二重予約が発生 — トランザクションは現在の予約の出力を隔離せず、レベルはREAD COMMITTED。
ストーリー
MySQLからPostgreSQLへの移行: 開発者はREPEATABLE READがファントムから保護されることに慣れていましたが、移行後に同じトランザクション内で再度のクエリで期待していない「保留中」の注文が表示されました。