トランザクションの状態とロック
先生:次にトランザクションの状態についてお話しましょう。信号機を思い出してください。信号機は、徒歩や自動車そして鉄道など2つの交通が交差する場所に設けられて、互いが衝突するのを防ぐ重要な役割を持っています。
由美:ということは、トランザクションにも信号機の青、黄、赤みたいな状態があって、トランザクション同士の干渉を防いでいるのですね?
先生:その通りです。トランザクションの場合は、だいたい図6のような状態に分けられます。さて、データベースを更新する際には、同時に別の人がデータを変更できると整合性が保証できなくなるという話をしたことがありましたね。
由美:はい。第1回で排他制御の話が出てきました。
先生:この排他制御の操作を「ロック」といいます。あるトランザクションがアクセス中のデータに対して、他のトランザクションからアクセスできないようにすることです(図7)。第1回の説明では、どれくらい細かく実行できるかをレベルという言葉で説明しましたが、正確には「粒度(Granularity)」と呼んでいます。
由美:粒度が細かいほど、制限できるデータ単位が小さくなるということですか?
先生:そうです。粒度が一番粗いのはデータベースで、次にテーブル、そして行、カラムというように粒度は細かくなります(図8)。
お父さん:じゃあロックの粒度は細かければよいのですね。
先生:そうとは限りません。もちろん、ロックの粒度が細かければ同時実行性が高くなって効率は向上します。しかし、ロックの粒度を細かくすればするほど、それだけデータベース管理システムのコスト(負荷)は大きくなります。したがって、システム全体をよく考えてロックの粒度を決めなければいけません。
先生:ところで中村さん、顧客からお金が入金されてしまったけれども、何らかの理由で取引が成立しなかった場合がありますよね? そうした場合はどうしますか?
お父さん:あまりあってはいけないことですが、そうした場合は顧客に同額を返金するという処理をします。
先生:そうですね。データベースも人が使うものですから、誤った値でデータを更新してしまうことはありえます。いったんコミットしてしまったものは元に戻せないわけですが、逆の操作をすることで見かけ上、元に戻すことはできます。これを「補償トランザクション」と呼んでいます。
お父さん:難しいようでも現実世界で手でやっていることと同じなんですね。もっとも、現実世界では、振り込み料金が発生してしまいますので、極力避けなければいけませんが。
分散データベースで原子性を保証する2相コミット
先生:あと「2相コミット」についても触れておきましょう。以前、データベース管理システムの機能の1つとして、同じものを別のサーバにコピーするレプリケーションを説明しました。しかし、このような分散データベースでは、それぞれのデータベースにトランザクションを同じように適用する必要があります。こうした状態でもさっきの原子性は保証しなければいけません。
由美:2相ってことはコミットを2回に分けて行なうのですか?
先生:そうです。第1相では同期を要求する側がデータベースを処理する先に対してデータベース更新の保証処理を依頼します。これを「プリペア(PREPARE)」と呼んでいます。
由美:保証処理というのは何ですか?
先生:保証処理というのはデータベースを更新前の状態にいつでも戻せるための処理と、実際の更新をいつでも正しくできるようにするための処理を行なうことです(図9)。
お父さん:そして第2相があるんですね?
先生:第2相では、同期を要求する側が第1相の結果を元にしてデータベースの更新を行なうか、更新前の状態に戻すかを決定して依頼することになります。
お父さん:なるほど、同期を取っているデータベース処理元の中に1つでもプリペアが失敗したものがあればアボートとなり、すべてのプリペアが成功していれば、コミットとなるのですね。
先生:そうです。2相コミットによって同期状態にあるすべてのデータベースは、更新が正しく行なわれたか、まったく行なわれなかったかという原子性を保つことができるのです。
お父さん:あっ、もうこんな時間ですね。
先生:すっかり日が短くなりましたね。今日はこのへんにしておきましょうか。次回はSQLについて勉強することにしましょう。
由美・お父さん:次回もよろしくお願いします。
この連載の記事
-
最終回
ソフトウェア・仮想化
「せんせい!SQLってRDBを操作する言語よね?」(由美) -
第2回
ソフトウェア・仮想化
「由美ちゃん、これがRDBの要素だよ」(先生) -
第1回
ソフトウェア・仮想化
「データベースってなんですか?」(由美) - この連載の一覧へ