データベーススペシャリスト 2018年 午前2 問14
問題文
厳格な2相ロッキングプロトコルと表ロックを適用して、同時実行している他のトランザクションの処理結果に影響を与えないようにする。実現されるトランザクションの隔離性水準はどれか。
選択肢
ア:READ UNCOMMITTED
イ:READ COMMITTED
ウ:REPEATABLE READ
エ:SERIALIZABLE(正解)
🔒 解説は解答すると表示されます
直列化可能性【午前2解説】
正解の理由
厳格な2相ロッキング(Strict 2PL)と表ロックを組み合わせることで、トランザクションの実行結果が「ある直列実行順序」と等価になる、つまりシリアライザビリティ(直列化可能性)が実現されます。ここでの正解は エ(SERIALIZABLE)です。
理由の要点は次のとおりです。
- 厳格な2相ロッキングは、排他ロック(書込み用)をコミットまたはロールバックまで保持するため、未コミットデータの読み取り(ダーティリード)やコミット前の変更による一貫性破壊を防ぎます。また、共有ロックと排他ロックの取得順序により、同時実行による相互干渉が制御され、直列化可能性が担保されます。
- ただし、表ロックなどの広い粒度のロックを併用することで、挿入や削除による「ファントム現象」も防止できます。これにより、読み取り範囲に関する不整合(ファントムリード)まで抑止され、完全なシリアライザビリティが実現します。
重要な注意点:整合性(直列化可能性)は確保されますが、ロックを保持する設計上、他トランザクションのロック待ちやデッドロックが発生する可能性がある点は残ります。つまり「整合性を保つがロック待ちやデッドロックは発生し得る」という理解が正しいです。
解法ステップ
- 問題文から適用される仕組みを抽出する(厳格な2相ロッキング+表ロック)。
- 各仕組みが防ぐ現象を列挙する(ダーティリード、ノンリピート、ファントム等)。
- それらを防げる隔離レベルがどれかを定義と照合する。
- 定義に基づき選択肢を消去して正解を決定する(結果:エ)。
選択肢別の誤答解説
- ア: READ UNCOMMITTED
- 最も低い隔離レベルで、ダーティリードを許容します。厳格2PLとは相容れないため不正解です。
- イ: READ COMMITTED
- 未コミットデータの読み取りは防げますが、同一トランザクション内での繰返し読み取りが異なる結果になる(ノンリピートリード)や、ファントムは防げない場合があります。表ロックを用いるとはいえ、READ COMMITTED自体はシリアライザビリティを保証しません。
- ウ: REPEATABLE READ
- 同一トランザクション内の同一行の再読み取りについては同じ結果が得られることを保証しますが、実装によってはファントム(範囲に対する挿入)を防げないことがあります。表ロックを用いればファントムも防げますが、問題文は「厳格な2相ロッキング+表ロック」と組合せての効果を問うており、より厳密なシリアライザビリティ相当を示すのは エ です。
- エ: SERIALIZABLE
- トランザクションの結果がある直列実行に等しくなることを保証します。厳格な2相ロッキングに加え表ロックでファントムも抑止されるため、ここで求められる隔離水準はシリアライザビリティ、すなわち エ です。
よくある誤解
- 厳格な2相ロッキングは「同時実行による競合が発生しない」
- 誤り:整合性は保ちますが、ロック待ちやデッドロックは発生し得ます。競合(アクセス要求の競合)は発生するが制御され整合性違反を防ぐ、という理解が正しいです。
- REPEATABLE READとSERIALIZABLEを同一と考える
- 多くの実装でREPEATABLE READは行レベルの繰返し読み取りを保証しますが、ファントムの扱いで差が出ます。完全な直列化はSERIALIZABLEです。
- 表ロックをすれば副作用はゼロ
- 表ロックでファントムは防げますが、同時実行性は大幅に低下し、待ちやデッドロックのリスクが増します。
補足コラム
- シリアライザビリティの実現手法
- 代表的な手法としては(1)2相ロッキング(特に厳格2PL)、(2)タイムスタンプ順序付け、(3)MVCC(多版本制御)+検証(シリアライザビリティ保証のための検査)があります。MVCCでは読み取りは非ブロッキングで高速ですが、シリアライザビリティを保証するには追加の整合性チェックが必要です(例:Serializable Snapshot Isolation)。
- 実用上のトレードオフ
- 高い隔離レベル(SERIALIZABLE)は正しさを最大化しますが、スループット低下や待ち時間増加が生じます。業務要件に応じて、どの隔離レベルを選ぶかを設計段階で検討することが重要です。
- SQLでの表ロック例(参考)
- PostgreSQL: LOCK TABLE tbl IN SHARE MODE; や LOCK TABLE tbl IN EXCLUSIVE MODE; など(DBMSごとに文法は異なります)。
FAQ
Q1: 厳格な2相ロッキングと通常の2相ロッキングの違いは?
A1: 通常の2相ロッキングは「拡張(ロック取得)フェーズ」と「解放フェーズ」を守ることを指しますが、厳格な2PLは特に排他ロックをコミットまたはロールバックまで解放しない点を強調します。これにより回復可能性(カスケードロールバックの回避)が向上します。
A1: 通常の2相ロッキングは「拡張(ロック取得)フェーズ」と「解放フェーズ」を守ることを指しますが、厳格な2PLは特に排他ロックをコミットまたはロールバックまで解放しない点を強調します。これにより回復可能性(カスケードロールバックの回避)が向上します。
Q2: ファントムを防ぐには行レベルロックで足りるか?
A2: 行レベルロックだけでは、新たな行の挿入(範囲外のファントム)を防げないことがあります。範囲ロックや表ロック、インデックス上の適切なロックなどが必要です。
A2: 行レベルロックだけでは、新たな行の挿入(範囲外のファントム)を防げないことがあります。範囲ロックや表ロック、インデックス上の適切なロックなどが必要です。
Q3: MVCC環境でもSERIALIZABLEは可能か?
A3: 可能です。MVCCに対してシリアライザビリティを提供するためには、トランザクションのコミット時に競合検証(フィレンツ法やシリアライズ検査)を行う実装が用いられます(例:Serializable Snapshot Isolation)。
A3: 可能です。MVCCに対してシリアライザビリティを提供するためには、トランザクションのコミット時に競合検証(フィレンツ法やシリアライズ検査)を行う実装が用いられます(例:Serializable Snapshot Isolation)。
関連キーワード: ロック、2相ロッキング、厳格2PL、シリアライザビリティ、隔離レベル、ファントムリード、デッドロック、MVCC、範囲ロック、表ロック

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

