マルチユーザー環境における問題(ロストアップデート)

複数のユーザーが1つのデータベース(テーブル)を更新するとき、さまざまな問題が発生します。 その中の1つロストアップデートの動作と解決方法を紹介します。

lost update img

CPUを購入しようとプロセスA(Aさん)とプロセスB(Bさん)が商品の在庫状況を確認します。

どちらにも在庫は 1点 あると表示されるはずです。

そこで、AさんがCPUの購入を決め購入したとします。

すると、その時点でCPUの在庫は 0点 なのですが、Bさんの画面上は 1点 あるように 見えています。

その後、Bさんも購入を決定しますが在庫は 0点 なので買うことができないのですが これを事前にBさんに知らせることはできません。

このまま実行すると、在庫数が -1点 となり在庫数がおかしくなります。

これを ロストアップデート といいます。

ロストアップデートを解決する手段はいくつか考えられます。例えば、Oracleの場合トリガを使って解決する方法があります。 ここでは、MySQLで解決する方法を紹介します。

ロストアップデート 対策

テーブルに各レコードの更新状態を管理するカウンター項目を追加します。

商品の在庫状況を照会する際、このカウンター情報も同時に取得します。

Aさんが購入を決定して購入するとき、在庫数の更新条件としてこのカウンターも追加します。 さらにカウンターの値も更新します。

その後、Bさんも購入を決定して購入するとします。 しかし、Aさんが購入したことでカウンターが 1 に更新されています。 そのためBさんの在庫数の更新は、失敗します。

update文発行後、更新された行数を確認することで購入できたかどうかを判断することができます。 更新行数が 0件 だった場合、リトライする等の処理を行います。

以上で、ロストアップデートは解決できます。