基本情報技術者 2013年 秋期 午前(科目A) 問31
問題文
“商品”表に対して、更新SQL文を実行するトランザクションが、デッドロックの発生によって異常終了した。異常終了後の“商品”表はどれか。ここで、“商品”表に対する他のトランザクションは、参照は行うが更新はしないものとする。


選択肢
ア:
イ:(正解)
ウ:
エ:
DELETE が異常終了(デッドロック)した場合の “商品” 表の状態【午前2 解説】
要点まとめ
- 結論:DELETE を実行したトランザクションはデッドロックで異常終了しロールバックされるため、"商品"表は実行前と同じ状態で変更は反映されない。
- 根拠:トランザクション一貫性の原則により、異常終了時は未コミットの変更は取り消され、変更前のデータが復元される(ロールバック)。
- 差がつくポイント:ロールバックと「部分的な変更」や「NULL への置換」を混同しないこと。非トランザクショナル表や異なる隔離レベルを想定すると誤答しやすい。
正解の理由
正解は イ です。理由は、DELETE 文を含むトランザクションがデッドロックで異常終了した場合、データベースはそのトランザクションの未コミットの変更をすべて取り消す(ロールバックする)ためです。よって削除は確定しておらず、元の行(B020, BBB, 1,000)は残ったままになります。問題文は他のトランザクションが参照のみで更新しないと明示しており、参照側の影響も考慮しなくてよいため、表は元のまま(選択肢イ)です。
よくある誤解
- 誤解1:トランザクションが途中で中断すると「一部の列だけが NULL になる」や「行の一部だけ消える」と思う。
→ 実際は未コミットの変更はすべて取り消され、部分コミットは発生しません(トランザクション性の前提下では)。 - 誤解2:異常終了=データベース全体の破損と考える。
→ トランザクション単位でロールバックされ、他の正常なデータは保護されます。非トランザクショナルなエンジンは例外です。 - 誤解3:読み取りトランザクションが変更を見ているため変更は残ると考える。
→ 標準的な隔離レベル(READ COMMITTED 以上)では未コミットの変更は他トランザクションから可視化されません。READ UNCOMMITTED の場合は「ダーティリード」があり得ますが、問題文の想定では通常のロールバックが適用されます。
解法ステップ
- 問題文を読み、どの操作が行われたかを確認(DELETE FROM 商品 WHERE 商品コード = 'B020')。
- その操作が「トランザクション内で実行され、デッドロックで異常終了した」とある点を把握。
- トランザクションが異常終了した場合のDBの動作(未コミット変更はロールバック)を思い出す。
- 他のトランザクションは参照のみで更新しないとあるので、参照による可視性を過度に考えない。
- よって元の表のまま(B020 の行が残る)である選択肢を選ぶ。
選択肢別の誤答解説
- ア:B020 の「商品名」が NULL になっているが、DELETE は行を削除する操作であり、部分的に列だけ NULL になるという説明はトランザクションの振る舞いと合致しません。異常終了ならロールバックされ、元に戻ります。
- イ:イ は正解。トランザクションが異常終了したためロールバックされ、表は元のまま(A010, B020, C030 全て残る)です。
- ウ:B020 が消えている(3行になっている)が、DELETE が未コミットのまま異常終了しているため行は消えません。コミットされていればこの選択肢が正しくなりますが、条件からそうではありません。
- エ:A010 と C030 が消えて B020 のみ残っているという全く異なる状態ですが、与えられた SQL は B020 を削除する文であり、このような変化を説明できません。
補足コラム
- デッドロック発生時の一般的な処理は「デッドロック検出→一方のトランザクションを強制終了→ロールバック」です。これによりデータ整合性が保たれます。
- DB エンジンによっては MVCC(例:PostgreSQL、InnoDB)を採用しており、読み取りは古いスナップショットを使うため未コミットの変更を読まない設計です。逆に MyISAM のような非トランザクショナルストレージではトランザクション原則が適用されず注意が必要です。
- 問題文で「参照は行うが更新はしない」とある場合、読み取り側がロック争いを起こしている可能性はあるものの、最終的な表の状態はロールバックの有無に依存します。
FAQ
Q1. もし DB の隔離レベルが READ UNCOMMITTED ならどうなる?
A1. READ UNCOMMITTED ではダーティリードにより未コミット変更を読む可能性がありますが、トランザクションがロールバックされれば最終的な永続データには反映されません。問題は最終表の状態を問うているためロールバック後の状態を考えます。
A1. READ UNCOMMITTED ではダーティリードにより未コミット変更を読む可能性がありますが、トランザクションがロールバックされれば最終的な永続データには反映されません。問題は最終表の状態を問うているためロールバック後の状態を考えます。
Q2. 非トランザクショナルテーブル(例:MyISAM)の場合は?
A2. 非トランザクショナルストレージはトランザクションのロールバックをサポートしないため、異常終了時に変更が残る場合があります。試験問題では通常トランザクション性がある前提です。
A2. 非トランザクショナルストレージはトランザクションのロールバックをサポートしないため、異常終了時に変更が残る場合があります。試験問題では通常トランザクション性がある前提です。
Q3. デッドロックでどのトランザクションが強制終了される?
A3. DB は通常コストやタイムスタンプなどのポリシーで「犠牲者」を選び、そのトランザクションを強制終了してロールバックします。
A3. DB は通常コストやタイムスタンプなどのポリシーで「犠牲者」を選び、そのトランザクションを強制終了してロールバックします。
関連キーワード: ロック、デッドロック、トランザクション、ロールバック、隔離レベル、MVCC、コミット、整合性、読み取り可視性

\ せっかくなら /
基本情報技術者を
クイズ形式で学習しませんか?
クイズ画面へ遷移する→
すぐに利用可能!

