テクノロジ系データベース出題頻度 ★★★

トランザクションと排他制御

銀行振込を例に、ひとまとまりの処理「トランザクション」とコミット・ロールバックを解説。同時更新で数字が狂う仕組みと、それを防ぐロック(排他制御)、デッドロック、障害回復のロールフォワードまで図でわかり、データベースの信頼性を問う問題が解けるようになります。

この単元の用語:トランザクション / コミット / ロールバック / ACID特性 / 排他制御 / 共有ロック / 専有ロック / デッドロック / ロールフォワード / ログファイル

銀行で振込している最中に、システムが止まったらお金はどうなるんですか?

そこで登場するのがトランザクション。「引き落とし」と「入金」をひとまとまりとして扱って、途中で止まったら全部なかったことにするんだ。

トランザクション:ひとまとまりの処理

トランザクション は、データベースに対する これ以上分けてはいけない一連の処理のまとまり です。

銀行振込(AさんからBさんへ1万円)

  1. Aさんの口座から1万円を引く
  2. Bさんの口座に1万円を足す

1だけ実行されて2の前にシステムが止まると、1万円が消えてしまいます。1と2は「両方やる」か「両方やらない」かのどちらかでなければなりません。

  • コミット:トランザクションの処理がすべて成功したら、結果を 確定 させる
  • ロールバック:途中で失敗したら、それまでの更新を 取り消して開始前の状態に戻す

ACID特性

トランザクションが満たすべき4つの性質を、頭文字をとって ACID特性 といいます。

性質意味振込の例
原子性(Atomicity)すべて実行されるか、まったく実行されないか引き落としだけ、は起きない
一貫性(Consistency)データに矛盾がない状態を保つ2人の残高の合計は振込の前後で変わらない
独立性(Isolation)同時に実行しても、互いに影響しない別の人の振込と同時でも結果が狂わない
耐久性(Durability)確定した結果は障害が起きても失われないコミット後に停電しても振込は有効

同時に更新すると何が起きる?

ネットショップで、在庫100個の商品をAさんが30個、Bさんが20個、ほぼ同時に 注文したとします。

処理A(−30) 在庫データ 処理B(−20) ① 100を読む 100 ② 100を読む ③ 70を書く 70 ④ 80を書く 80 本当は 100 − 30 − 20 = 50 のはず。Aの更新が消えた!
Bは古い値「100」をもとに計算したため、Aの書き込みを上書きしてしまう

在庫は本当は50個なのに、データ上は80個になってしまいました。この現象を 更新の喪失(ロストアップデート)といいます。

排他制御:ロックで順番待ちさせる

これを防ぐのが 排他制御 です。あるトランザクションがデータを使っている間、そのデータに ロック(鍵) をかけて、他のトランザクションを待たせます。上の例では、AがロックをかけてAの更新が終わるまで、Bは在庫を読めません。Bは70を読んでから20を引くので、正しく50になります。

試着室の鍵 をイメージしよう。中に人がいる間は鍵がかかっていて、次の人は外で待つ。出てきたら(ロック解除)次の人が入れる。

ロックには2種類あります。

種類使う場面他のトランザクションは
共有ロック(読取りロック)データを 読む とき読むことはできる。書くことはできない
専有ロック(排他ロック、書込みロック)データを 更新する とき読むことも書くこともできない

ロックをかける範囲を広くすると安全ですが、待ち時間が増えて 処理が遅くなります。表全体ではなく必要な行だけにロックをかけるなど、範囲を小さくする工夫がされています。

デッドロック:お互いに待ち続ける

ロックを使うと、困った状態が起きることがあります。

トランザクション1 トランザクション2 🔒 データX 🔒 データY ロック中 ロック中 Yの解除待ち → ← Xの解除待ち どちらも相手の鍵が外れるのを待ち、永遠に進まない
1はXを持ったままYを待ち、2はYを持ったままXを待つ

このように、互いに相手がロックしているデータの解除を待ち続け、処理が進まなくなる状態 を デッドロック といいます。DBMSはデッドロックを検出すると、どちらか一方のトランザクションをロールバックさせて解消します。予防策としては、すべてのトランザクションでロックをかける順番をそろえる(必ずX→Yの順にする)ことが有効です。

障害回復:ログとバックアップで元に戻す

DBMSは、データを更新するたびに ログファイル(ジャーナル)に記録を残しています。ログには 更新前の値 と 更新後の値 が記録されます。障害が起きたら、これを使って回復します。

ロールバックとロールフォワード、名前が似ていて逆になりそうです…。

back=後ろへ戻る、forward=前へ進む。途中までの処理を「なかったこと」にするのがバック、バックアップから最新まで「やり直して進める」のがフォワードだよ。

回復方法使うもの戻る状態主な場面
ロールバック更新前 ログトランザクション 開始前処理の途中でエラーが起きた、デッドロックの解消
ロールフォワードバックアップ + 更新後 ログ障害発生 直前(コミット済みの状態)ディスクの故障(媒体障害)

試験に出るポイント

  • トランザクション:分けてはいけない処理のまとまり。成功したら コミット、失敗したら ロールバック
  • ACID特性:原子性(全部か無か)・一貫性・独立性・耐久性
  • 同時更新で値が狂うのを防ぐのが 排他制御(ロック)。読むときは 共有ロック、書くときは 専有ロック
  • デッドロック:互いに相手のロック解除を待ち続ける状態。ロックの順番をそろえて予防
  • ロールバック は更新前ログで開始前へ、ロールフォワード はバックアップ+更新後ログで障害直前へ

確認クイズ

選択肢をタップすると、すぐに正解と解説が表示されます。

Q1在庫数が100の商品について、処理Aは在庫を30減らし、処理Bは在庫を20減らす。排他制御をせずに、次の順で処理が行われた。最終的な在庫数はいくつになるか。
1. Aが在庫数(100)を読む
2. Bが在庫数(100)を読む
3. Aが 100 − 30 の結果を書き込む
4. Bが 100 − 20 の結果を書き込む

Q2データベースを格納したディスクが故障した。ディスクを交換した後、バックアップファイルを復元し、更新後ログを使って障害発生直前の状態まで回復させる方法はどれか。

Q3デッドロックの説明として、適切なものはどれか。

Q4トランザクションに求められる性質のうち、「処理はすべて実行されるか、まったく実行されないかのどちらかでなければならない」というものはどれか。