GoTheDistance

ござ先輩と言われています。(株) クオリティスタートという会社をやっています。

長時間トランザクションを考える

業務を実行するにあたり、システム上避けて通れないトピックが長時間トランザクションというヤツ。「短時間で終了させることはできないが、論理的にはひとかたまりとして処理しなければならないトランザクション処理」のことです。

ここでいう短時間とは「ポチっと画面からボタン押してUPDATE文一発流しておわり」という意味です。マスタメンテとかがそれに当たるかも。でも、それだけですむ場合もあれば、複数画面や複数システムにまたがっているのでそうもいかねぇだろ、っていうのもあります。業務をまたがってトランザクションを確保しなくてはならないケースも多数あるはずです。

@ITで、非常に分かりやすい長時間トランザクションが必要な例があります。電車の座席予約システムの例です。

http://www.atmarkit.co.jp/fdotnet/entwebapp/entwebapp10/entwebapp10_03.jpg

長時間トランザクションの実装方法

物理的にトランザクションロックかけるのは非現実的なので、「論理的に」これは1つの処理単位なのであるということを示す必要があります。

1つはカラムに編集状態を示すフラグをもつことです。

例えば座席確保の画面を表示した段階では、A1という座席が空いていたとします。確保の画面を開いた段階で既に「hoge編集中」フラグを設けます。なので、他のユーザーがA1ゲットしようとしても「hogeさんが編集中だからその座席は取れませんよ」という排他制御をかけることができます。hogeさんはキャンセル or 確保確定みたいなイベントを発行して、編集状態カラムをクリアするなどを行います。

2つ目はカラムの突合せをやる方法です。

何でもいいんですけど、そのレコードの更新対象をまず保持していて、UPDATEかける時にその更新対象が変化していないかどうかをチェックします。更新時刻をTimeStamp型で保持しておいて、んでもって更新時にそのTimeStampとDBのTimeStampを見比べて、DBの時間の方が新しいなら更新があったとみなし、UPDATEしないっていうやり方。多分よくやる方法だし、私もこの方法を取る。

他の方法はあるのか?

なんかありますかね?もっとスマートなのがあるぜ、みたいな。

合わせて読みたい

■楽観的制御でいいじゃん
http://blogs.sqlpassj.org/akiraonishi/articles/5026.aspx