トランザクション分離レベル
並行するトランザクションから“途中経過をどこまで見せるか”を決める設定です。緩いほど速く、厳しいほど安全という性能との trade-off を解説します。
- 1.分離レベルは Read Uncommitted / Read Committed / Repeatable Read / Serializable の4段階。
- 2.緩いほど高速だがダーティリード・ファントムなどの異常が起きやすく、厳しいほど安全だが遅くなる。
- 3.多くのDBの既定は Read Committed。必要な範囲だけレベルを上げるのが定石。
分離レベルとは
データベースは普通、多数のトランザクションを 同時に さばきます。完全に1件ずつ順番待ち(直列)にすれば安全ですが遅い。そこで「並行する他のトランザクションの途中経過を、どこまで見せるか」を段階的に選べるのが 分離レベル (Isolation Level) です。
緩いほど速く、厳しいほど安全――この trade-off を理解することが要点です。
防ぎたい3つの異常(アノマリー)
レベルを緩めると起きうる代表的な不具合は次の3つです。
| 異常 | 何が起きる | ひとことで |
|---|---|---|
| ダーティリード | 他がまだコミットしていない(取り消されるかもしれない)変更を読む | 未確定の値を読む |
| ノンリピータブルリード | 同じ行を2回読むと、間に他のコミットが入り値が変わる | 同じ行の値がブレる |
| ファントムリード | 同じ条件で2回検索すると、間に挿入・削除され件数が変わる | ヒット件数がブレる |
ノンリピータブルリードは「同じ1行の値が変わる」、ファントムリードは「条件にヒットする行数が変わる」点が違いです。
4つの分離レベル
SQL 標準は、これらをどこまで防ぐかで4段階を定めています。
| 分離レベル | ダーティリード | ノンリピータブル | ファントム |
|---|---|---|---|
| READ UNCOMMITTED | 起きうる | 起きうる | 起きうる |
| READ COMMITTED | 防ぐ | 起きうる | 起きうる |
| REPEATABLE READ | 防ぐ | 防ぐ | 起きうる(*) |
| SERIALIZABLE | 防ぐ | 防ぐ | 防ぐ |
設定はトランザクション単位で指定できます。
BEGIN;
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
-- ...処理...
COMMIT;
上の表は SQL 標準が定める「最低限ここまでは防ぐ」という線引きです。実際のDBはもっと強いことが多く、(*) を付けた REPEATABLE READ でも、たとえば PostgreSQL の実装ではファントムリードまで防ぎます。自分が使う製品が実際に何を保証するかは、必ずその製品のドキュメントで確認してください。既定レベルも製品ごとに違います(多くは READ COMMITTED)。
性能との trade-off
レベルを上げるほど、DB はロックを長く保持したり、競合時に再試行(シリアライズ失敗)を要求したりします。その結果、待ち時間やデッドロックが増え、スループットが落ちます。
- READ COMMITTED: 多くのWebサービスの実用的な既定。各文の実行時点で確定済みのデータを読む。
- REPEATABLE READ: 同じトランザクション内で読み取りの一貫性が必要なとき(集計・レポートなど)。
- SERIALIZABLE: 一切の異常を許さない厳密な処理。ただしコストは最も高い。
一番厳しい SERIALIZABLE にすれば異常は消えますが、その分ロック待ちや再試行が増え、性能が大きく落ちることがあります。まず「どの異常が、どの処理で本当に問題になるか」を見極め、必要な範囲だけレベルを上げるのが定石です。常に最強設定が正解ではありません。
どう選ぶか
- 既定(多くは READ COMMITTED)で困らないかをまず確認する。
- 同じトランザクション内で何度も読む値がブレては困るなら REPEATABLE READ。
- 在庫の二重引き当てなど、整合性が絶対のごく一部だけ SERIALIZABLE にする。
分離レベルは「正しさ」と「速さ」を天秤にかける道具です。アプリ全体を一律に厳しくするのではなく、処理ごとに必要な強さを選ぶことで、安全と性能を両立できます。
データベース Article
トランザクション分離レベルを実務で読む
TL;DRは入口です。実際に選ぶ・使う段階では、何を解決するか、何と比較するか、導入後にどこで詰まるかまで見る必要があります。
解決すること
分離レベル
比較で見る軸
難易度: intermediate / カテゴリ: データベース / タグ数: 4
導入後に効く点
緩いほど高速だがダーティリード・ファントムなどの異常が起きやすく、厳しいほど安全だが遅くなる。
先に潰すリスク
用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。
- 難易度
- intermediate
- カテゴリ
- データベース
- タグ数
- 4
判断チェックリスト
- 自社の用途が「分離レベル / トランザクション」に近いか確認する。
- 強みである「分離レベルは Read Uncommitted / Read Committed / Repeatable Read / Serializable の4段階。」が本当に評価軸になるか確認する。
- 注意点の「用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。」を運用で吸収できるか確認する。
- 公開値や仕様値は、対象プラン・対象機種・対象リージョンまで確認する。
- 既存システム、ID、ネットワーク、監視、バックアップとの接続方法を先に洗い出す。
- 小さく試してから、本番移行、権限設計、障害時手順、コスト監視を決める。