データベーススペシャリスト 2014年 午前2 問14
問題文
データベースのトランザクション T2 の振る舞いのうち、ダーティリード (dirty read)に関する記述はどれか。
選択肢
ア:トランザクション T1 が行を検索し、トランザクション T2がその行を更新する。その後 T1は先に読んだ行を更新する。その後に T2 が同じ行を読んでも、先の T2 による更新が反映されない値を得ることになる。
イ:トランザクション T1 が行を更新し、トランザクション T2がその行を検索する。その後 T1 がロールバックされると、T2 はその行に存在しない値を読んだことになる。(正解)
ウ:トランザクション T2 がある条件を満たす行を検索しているときに、トランザクション T1 が T2 の検索条件を満たす行を挿入する。その後 T2 が同じ条件でもう一度検索を実行すると、前回は存在しなかった行を読むことになる。
エ:トランザクションT2が行を検索し、トランザクション T1 がその行を更新しコミットする。その後 T2 が同じ行を検索した場合、同じ行を読んだにもかかわらず、異なる値を得ることになる。
🔒 解説は解答すると表示されます
ダーティリード【午前2解説】
正解の理由
選択肢イは、あるトランザクション(T1)が行を更新した直後に別のトランザクション(T2)がその更新済みの値を読み取り、その後 T1 がロールバックして更新が取り消されるため、T2 は「存在しない(最終的にはなかった)値を読んだ」ことになる、という流れを記述しています。これがまさに「ダーティリード(dirty read、未コミット読み)」の定義です。未確定(未コミット)の更新を別トランザクションが参照し、その更新が取り消される可能性がある点が決定的です。
解法ステップ
- 各選択肢の時系列(更新・読み取り・コミット/ロールバックの順)を追う。
- 「読んだ値が後にロールバックで消える」場合はダーティリードの典型。
- 「読んだ後に別トランザクションがコミットする」場合は非リピータブルリード等、別の現象と判定する。
- 選択肢にコミット/ロールバックの記述がなければ、その有無で現象の成立可否を評価する。
上の手順に従うと、更新→読み取り→ロールバックの順序が含まれる イ がダーティリードであると判定できます。
選択肢別の誤答解説
-
ア: 説明が内部で矛盾しています。T2 が自分で行った更新を後で読み直して「更新が反映されていない値を得る」とありますが、同一トランザクション内で自分の更新を見えなくすることは通常のトランザクション整合性では起きません(コミットや他トランザクションの振る舞いが明記されていないため、ダーティリードとは言えません)。したがって誤りです。
-
イ:(正解)T1 が更新→T2 が読み取り→T1 がロールバック、という流れは「未コミットのデータを他トランザクションが読んだ」典型でありダーティリードです。読み取ったデータが最終的に存在しないことになる点が本質です。
-
ウ: これはファントムリード(phantom read)の記述です。ある検索条件で行を探している最中に他トランザクションが条件に合致する行を挿入し、再検索すると新しい行が現れる現象を指します。読み取り対象の「行集合」が変わる点が特徴で、ダーティリードとは別現象です。
-
エ: 同じ行を T2 が2回読み、その間に T1 が更新してコミットしたために値が変わる、という記述は「非リピータブルリード(非再現リード)」です。ポイントは更新がコミットされていることで、T2 が読んだ最初の値は後に永続的に変化しており「未コミット読み」ではない点でダーティリードとは異なります。
よくある誤解
- ダーティリードと非リピータブルリードを混同する:どちらも「同じ行を読み直して値が変わる」ように見えるが、ダーティリードは「読み取った更新がロールバックされる(未コミット)」場合、非リピータブルリードは「他トランザクションがコミットして値が恒久的に変わる」場合で区別される。
- ファントムと非リピータブルリードの混同:非リピータブルは同一行の値の変化、ファントムは検索結果(行の集合)の増減が問題になる。
- 「読み取りの不整合は常に発生する」は誤り:隔離レベルにより発生可否が制御される。
補足コラム
- 代表的なトランザクション異常と防止される隔離レベル(一般的な関係)
- ダーティリード:Read Uncommitted で発生。Read Committed 以上で防止。
- 非リピータブルリード:Read Committed では発生するが Repeatable Read 以上で防止(実装差あり)。
- ファントムリード:Repeatable Read でも実装次第では発生、Serializable で完全に防止。
- 実務上はデータベース製品ごとに既定の隔離レベルと実装が異なるため、具体的な挙動はドキュメントで確認すること。
- 簡単な再現例(概念示例):
-- T1 BEGIN; UPDATE accounts SET balance = balance + 100 WHERE id = 1; -- 未コミット -- T2 SELECT balance FROM accounts WHERE id = 1; -- T1 の未コミット更新を読む(ダーティリード) -- T1 ROLLBACK; -- 更新取り消し。T2 は存在しない値を読んでいたことになる
FAQ
Q. ダーティリードを避けるためにどの隔離レベルを選べばよいですか?
A. 最低でも Read Committed を選ぶとダーティリードは防げます。ただし他の一貫性問題(非リピータブルやファントム)は発生する可能性があるため、要件に応じて上位の隔離レベルを検討してください。
A. 最低でも Read Committed を選ぶとダーティリードは防げます。ただし他の一貫性問題(非リピータブルやファントム)は発生する可能性があるため、要件に応じて上位の隔離レベルを検討してください。
Q. 読み取り一貫性を完全に保つと性能はどうなりますか?
A. 高い隔離レベル(Serializable)は一貫性を高めますがロック競合やスループット低下を招くため、性能要件と整合性要件のバランスが重要です。
A. 高い隔離レベル(Serializable)は一貫性を高めますがロック競合やスループット低下を招くため、性能要件と整合性要件のバランスが重要です。
Q. データベース製品ごとに用語や動作が違いますか?
A. はい。用語は共通でも既定の隔離レベルや実装(行レベルロック、MVCCなど)により現象の発生条件が変わるため、実際の挙動は製品ドキュメントで確認してください。
A. はい。用語は共通でも既定の隔離レベルや実装(行レベルロック、MVCCなど)により現象の発生条件が変わるため、実際の挙動は製品ドキュメントで確認してください。
関連キーワード: トランザクション、隔離レベル、ダーティリード、非リピータブルリード、ファントムリード、コミット、ロールバック、ACID

\ せっかくなら /
データベーススペシャリストを
クイズ形式で学習しませんか?
クイズ画面へ遷移する→
すぐに利用可能!

