口座Aから口座Bへ振り込む処理は、Aの残高を減らす更新とBの残高を増やす更新の 二つからなり、この二つを一つのトランザクションとして扱っている。Aの更新が 終わった直後に障害が起きたときの動作として、最も適切なものはどれか。
正解:イ
アAの残高を減らす更新だけを確定させ、Bへの入金は次の機会にやり直す。
誤り。お金が消えた状態が残ってしまいます。トランザクションは一部だけを 確定させないための単位なので、途中まで成功していても、まとめて 取り消すか、まとめて確定させるかのどちらかしかありません。
イ二つの更新をいずれも取り消し、トランザクション開始前の状態に戻す。
正解。ロールバックです。途中で失敗したときは、始める前の状態に戻すことで 「引き落としだけ済んでいる」という中途半端な状態を残しません。
ウ二つの更新をそのまま確定させ、以後は他の処理からも参照できるようにする。
誤り。コミットの説明で、これは最後まで成功したときの動作です。障害が 起きた今回に当てはめると、実際には行われていない入金まで確定して しまいます。成功時か失敗時かで動作が逆になる点が要点です。
エ前日に取得しておいた複製を使い、データベース全体を前日の状態へ戻す。
誤り。バックアップからの復旧です。媒体の故障などでデータそのものが 失われたときの手段で、戻る先は別の時点、対象はデータベース全体です。 今回のように処理だけを取り消したい場面の手段ではありません。
「全部やる」か「全部やらない」か
振込は、引き落としと入金がそろって初めて意味をもちます。引き落としだけが 残った状態は、どこから見ても誤りです。そこでデータベースでは、切り離せない 複数の更新をトランザクションという一つのまとまりとして扱い、 途中の状態のままでは終わらせないようにしています。
- コミット … 最後まで成功したので、更新をまとめて確定させる
- ロールバック … 途中で失敗したので、更新をまとめて取り消し、開始前に戻す
確定と取消しのどちらか一方しか起こらないので、「引き落としだけ済んだ」という 中間の状態が他の利用者から見えることはありません。この、まとめて全部か まったくやらないかという性質を原子性と呼ぶこともあります。
ロールバックとバックアップからの復旧は別物
言葉はどちらも「元に戻す」ですが、戻る先も対象も違います。
| 手段 | 何を、どこまで戻すか |
|---|---|
| ロールバック | 実行中のトランザクションの更新を、その開始時点まで |
| コミット | 戻さない。更新を確定させて反映する |
| 一部だけ確定 | 起こしてはいけない状態(トランザクションが防ぐ対象) |
| バックアップからの復旧 | 取得しておいた別時点の複製へ、データベースを丸ごと |
試験では「途中で失敗したら」という条件がロールバックの合図です。逆に 「無事に終わったら」ならコミット、「ディスクが壊れたら」ならバックアップ、 と読み分けると迷いません。