seegongsik
データ

わかりやすく トランザクション とは

友だちに千円を送るとしましょう。自分の残高から千円を引き、友だちの残高に千円を足さなければなりません。ところが、引く方は終わったのに、足す直前に電源が切れたらどうなるでしょうか。お金は自分の口座から出ていったのに、友だちは一円も受け取れません。こうした事故を防ぐために、いくつもの変更を一つにまとめ、全部済ませるか、全部やめるかにする方法がトランザクションです。

01

振りこみは、引くと足すの組です

前のレッスンでは、情報を一か所だけに置くように表を分けました。それでも、直す場所が一つではすまない仕事があります。口座の振りこみがそうです。自分の残高からお金を引き、受け取る人の残高に同じだけ足さなければなりません。
この二つは、切り離せない組です。片方だけ済むと、お金が消えるか、なかったお金がわいて出ます。下で、二つの変更を別々にやってみましょう。

自分の残高30
友だちの残高10
二つの合計40
二つのボタンを別々に押しましょう

引くと足すを別々に押してみましょう。片方だけ押すと二つの合計が変わり、お金が消えるか、なかったお金が出てきます。

引くだけを押すと自分のお金が消え、足すだけを押すとなかったお金が出てきます。どちらにしても、二つの残高の合計が最初とちがってしまいます。振りこみはお金を移すだけなので、合計は変わらないはずです。
危ないのは、引くと足すの間の短いすきまです。そのすきまに電源が落ちたりプログラムが止まったりすると、帳簿は食いちがったまま残ります。そこで、二つの変更を一つに結ぶ方法が必要になります。

02

全部済ませるか、全部やめるか

方法は単純です。引くと足すを一つのまとまりにし、このまとまりをトランザクションと呼びます。まとまりの中の変更は、すべて仮のものとしておきます。
全部そろったら確定して一度に本当に反映し、一つでもうまくいかなければ全部取り消します。確定することをコミット、取り消して元に戻すことをロールバックといいます。こうすれば、半分だけ反映された状態は生まれず、ほかの人からも途中の状態は見えません。この性質を原子性といいます。それ以上分けられない一つのまとまり、という意味です。

一つのまとまり(トランザクション)
引くを入れる
足すを入れる
自分の残高30
友だちの残高10
二つの変更をまとまりに入れましょう

二つの変更を一つのまとまりに入れてみましょう。両方入ってはじめて確定でき、取り消すと入れた変更が両方消えます。

確定すると二つの残高がいっしょに変わって合計はそのまま、取り消すと両方きれいに消えます。どちらにしても、帳簿は食いちがいません。まとめて扱っただけで、危ないすきまがなくなりました。
では、まとまりの中で作業している途中に、本当に電源が切れたらどうなるでしょうか。仮にしておいた変更は、どう扱われるのでしょうか。

03

途切れても、まるごと元に戻す

データベースは、変更する前に、何をどう変えるのかをログという記録に先に書いておきます。始める前の状態に戻るための情報も、いっしょに残します。
そのため、途中で電源が切れても、ふたたび動き出したときにログを読めば、終わらなかったまとまりを見つけられます。そして、半分だけ残すのではなく、そのまとまりを始める前の状態にまるごと戻します。反対に、確定まで終わったまとまりは、電源が切れたあともそのまま残ります。確定した結果が失われないこの性質を、永続性といいます。

始める前の状態(別に書いておく)30 / 10
自分の残高30
友だちの残高10
一つ進めてから、途切れを起こしましょう

一つ進めてから、電源の途切れを押してみましょう。半分だけ残さず、別に書いておいた始める前の状態にまるごと戻ります。

途切れたのに、帳簿は無事です。引くだけが反映されためちゃくちゃな状態ではなく、きれいに始める前へ戻りました。これがロールバックです。
失敗しても跡が残らないので、最初からやり直せばすみます。振りこみの前でも後でも、帳簿の決まり、たとえば二つの残高の合計は変わらないという決まりが守られます。これを一貫性と呼びます。では、何人もが同じ残高を同時に直そうとしたら、どうなるでしょうか。

04

同時に来ても、順番に処理する

オペレーティングシステムの分野で見た競合状態を思い出しましょう。二つが同じ資源を同時にさわると、結果がもつれました。残高も同じです。
二人が同じ残高を同時に読み、それぞれ足した値を書きこむと、あとから書いた人が前の人の結果を上書きしてしまいます。一人分の変更がまるごと消えるのです。これを更新の消失(ロストアップデート)といいます。そこでデータベースは、ロックのような仕組みを使って、同じ行を直すまとまりを一つずつ順番に処理します。

人X(+5)+5
人Y(+8)+8
同じ残高100
同時に送ると、片方が上書きします

二人を同時に送ってみましょう。そのままだと、あとから書いた方が上書きして片方の変更が消え、順番に止めると両方足されます。

そのままでは片方の変更が消え、順番に処理すると両方とも反映されました。同時に来ても少しのあいだ列に並ばせ、一つのまとまりが終わってから次のまとまりを受けつけるのです。
このように、同時に動くまとまりどうしが、たがいの途中の状態を見られないように引き離す性質を、分離性(独立性)といいます。ただし、すべてを厳しく並ばせると遅くなるので、実際のデータベースでは、どれくらい厳しく引き離すかの段階を選べるようになっています。

05

まとめ

まとめるとこうです。いっしょに変わるべき変更を一つにまとめて、全部済ませるか、全部やめるかにします。途中で途切れたらログを見て始める前にまるごと戻し、確定した結果は電源が切れても残ります。
いくつものまとまりが同じところを同時に直そうとしたら、順番に並ばせて上書きを防ぎます。原子性、一貫性、分離性、永続性。頭文字をとってACIDと呼ばれるこの四つの約束が、トランザクションです。

要点四つを順に押しましょう
下の要点を上から順に押しましょう

要点を順に押して振り返りましょう。(振りこみは組 → 全部かゼロか → 食いちがったらロールバック → 同時でももつれない)

これで、データを安全に変えるための約束が分かりました。お金が消えていたすきまも、電源が切れて半分だけ残る事故も、同時に直して上書きし合う混乱も、一つのまとまりという考え方で防げます。
安全に変える方法の次は、速く読む方法です。同じデータを何度もデータベースまで取りに行くかわりに、近くに写しを置いておく方法を、次のレッスン「キャッシュ」で扱います。

一言でいうとトランザクションとは、いっしょに変わるべきいくつもの変更を一つのまとまりとして扱い、全部済ませるか、全部やめるかにする方法です。振りこみのように引くと足すが組になっているときは、両方そろってから確定し、一つでもうまくいかなければ全部取り消します。途中で電源が切れても、データベースは先に書いておいたログで終わらなかったまとまりを見つけ、始める前の状態にまるごと戻します。これをロールバックといいます。確定した結果は、電源が切れたあとも残ります。何人もが同じ残高を同時に直そうとしたときは、順番に処理して、たがいに上書きしないようにします。原子性、一貫性、分離性、永続性をまとめてACIDと呼び、この四つがトランザクションの約束です。
← データ
このページがお役に立ったなら支援する