同時更新の問題
テキストエディターなどの基本的に1人で使う「スタンドアローン」なアプリケーションとは異なり、業務アプリケーションは大勢が同時に使うことが前提です。
大勢が同時に使う場合、1人で使う場合とは大きく異なる点が1つあります。それは、「同じデータをほぼ同時に編集する」というケースが発生するということです。
同じデータをほぼ同時に編集した場合、何も対策をとっていなければ、わずかな差で後から編集を行った操作が採用されることとなります。しかし、それでは具合が悪い場合もあります。
本連載で作成している会議室予約システムで考えてみましょう。
すでに登録されている予約情報の時間を2人がほぼ同時に更新したとします。このとき、先に変更を行ったユーザーは、他のユーザーがほぼ同時に同じ予約を変更したとは思っていません。もちろんエラーも発生しないため、自分の行った変更が正しく反映されたと思うでしょう。
しかし実際は、後から変更したユーザーの入力内容で予約情報が上書きされてしまっています。
もちろん、変更を行った後、予約参照画面で確認することはできますが、自分が行った変更が無事に行われたかどうかを毎回確認することは、あまり現実的ではありません。
そこで、こういった同時更新を防ぐために行うのが排他制御です。
排他制御
排他制御とは、一言でいえば同じデータを複数人が同時に変更できないようにする仕組みです。変更できないようにすることを俗に「ロックする」と呼びます。
排他制御には、大きく次の2つの方法があります。
- 悲観的(Pessimistic, ペシミスティック)排他制御
- 楽観的(Optimistic, オプティミスティック)排他制御
それぞれについて説明していきましょう。
悲観的排他制御
悲観的排他制御では、更新対象のデータを読み出してから更新を終えるまでの間、他のユーザーがそのデータに触れないようロックします。
この方法の特徴として、
- ロックを取得したユーザーのみ更新が行える。
- トランザクションが長くなるとロック期間が長くなり、全体としてのパフォーマンスが落ちる。
といった点があります。
従って、トランザクションが短く、頻繁に更新され、なおかつ同時更新が多発するような場合、例えば金額の管理に向いています。
楽観的排他制御
楽観的排他制御では、更新対象データを最初に取得した時点ではデータをロックしません。
そのかわり、データを更新する直前に、他のユーザーによって更新されていないかどうかをチェックします。この時初めて対象データをロックします。
そして、他のユーザーによってすでに更新されていた場合、更新処理をキャンセルします。ユーザーにはキャンセルしたことを伝え、もう一度処理をやり直してもらうよう促します。
この方法の特徴としては、
- 複数のユーザーが並行して更新処理を行える。
- 反面、データの衝突(コンフリクト)が発生しやすい。
といった点があります。
従って、更新頻度がそれほど高くなく、同時に編集するユーザーが少ないような場合、例えばマスターメンテナンスなどでよく用いられます。