/note/tech

楽観的同時実行制御でいいかな?

要約:

■ 1. 楽観的同時実行制御の普及と盲信への警鐘

  • ADO.NETを使うと楽観的同時実行制御を容易に実装できる
  • 超有名な「楽観的ロックでいいじゃん!」のお陰で楽観的同時実行制御は特にWebアプリケーション開発では広く使われている
  • 大概のアプリケーションでは楽観的同時実行制御で十分なのかもしれない
  • しかし「楽観的同時実行制御こそが正義だ」と盲信されかねない空気に警鐘を鳴らす必要がある

■ 2. 悲観的ロックと楽観的ロックの定義

  • 大西彰さんの記事「楽観的ロックでいいじゃん!」による定義:
    • 悲観的ロック:ステートフルなロックで更新したい対象のリソースを照会して取得した直後から更新が終わるまでロックを維持することでロック時間は長時間でロックは独占的
    • 楽観的ロック:ほぼステートレスなロックで更新したい対象のリソースを照会してもロックはかけず本当に更新が必要になった段階でその対象リソースをロックすることでロック時間は短時間でロックは非独占的

■ 3. 同時実行制御の概念による整理

  • 悲観的同時実行制御:
    • 衝突が頻繁に発生する事が前提の同時実行制御
  • 楽観的同時実行制御:
    • 衝突が殆ど起こらない事が前提の同時実行制御
  • 楽観的同時実行制御は「競合・衝突が全くあるいは殆ど起こらないために衝突に関しては楽観的に考えてよい」ものである
  • 悲観的同時実行制御は「競合・衝突が殆どにおいて発生しトランザクション量も多いため衝突に関しては悲観的に考えなければならない」ものである

■ 4. よくある勘違いとその弊害

  • 肝要でありよく勘違いされるのが「DBMSのロックメカニズムを使うことが悲観的同時実行制御である」という事である
  • そのせいか長時間ロックを回避する為にWebアプリケーション開発では楽観的同時実行制御を大前提に設計をしてしまう事が多々ある
  • しかしトランザクション量が多く競合・衝突が頻発するにも関わらず楽観的同時実行制御を行ってしまうと極端に使い勝手の悪いアプリケーションになってしまう
  • 予約システムのように仮予約されたチケットがいざ購入の段になって「他の人に獲られました」ではクレームの嵐である
  • 仮予約チケットは他の人が見れないようにロックする必要がある
  • かといって長時間トランザクションにDBMSのロックメカニズムを使う訳にはいかない

■ 5. 業務排他制御という解決策

  • 独力で同時実行制御を作り込む事が考えられる
  • 「.NETエンタープライズWebアプリケーション開発技術大全Vol.5トランザクション設計編」では「業務排他制御」と表現されている
  • 「悲観的ロックを使わないで悲観的同時実行制御を行う」とでも表現できる
  • テーブルに排他制御専用の列を2つ3つ追加し編集ステータスや編集開始日時などをチェックすれば良いだけで実装自体は比較的容易である
  • ただし実装は容易でも業務フローの難易度は高くなる

■ 6. Webアプリケーションと楽観的同時実行制御の適性

  • クライアントユーザー数が多いであろうWebアプリケーションの方が楽観的同時実行制御には向いていないとさえ言える
  • ただしユーザー数が多くても大半のユーザーが参照アクションしか行わないのであればその限りではない
  • 楽観的同時実行制御が向いているのはマスタデータメンテナンス等を行うクライアントユーザー数の限られたWindowsアプリケーション等ではないか
  • もちろんWebアプリケーションでもあり得る
  • 「Webアプリケーションでは悲観ロックはあり得ない楽観同時実行制御こそが正」と決めつける前によくよく仕様を揉んでみるべきである
  • その要件は楽観的に考えられるかを検討する必要がある

MEMO: