0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

楽観ロック

0
Last updated at Posted at 2026-09-11
Page 1 of 11

ロックとは

ファイルへの書き込みやデータベースの更新などの際、データの整合性を守るために他のプロセスからの 同時アクセスを一時的に禁止する仕組み

本ページでは主にRDBを念頭に置いて話を進めます。


ロックの種類

  • 悲観ロック:真のロック
  • 楽観ロック:本質的にはロックではないかもしれない

ロックの使いどころ

同時に1人しか更新できない画面

  • 画面表示時に対象レコードのロックを獲得
  • 獲得できない場合は「他の人が編集中です」などと表示して戻る
  • 画面から離れるときにロックをリリース

悲観ロック

  • 1つのリソースは1つの「ロック」を持つ
  • ロックを獲得したプロセスしか処理を行えない
  • ロック獲得に失敗したプロセスの挙動は2種類
    • 取れるまで待つ
    • 失敗する

RDBの場合、レコードのロック、テーブルのロックなどが存在します。
データベースロックが発生することも・・・恐ろしい・・・


悲観ロックとWeb

  • Webアプリは、終了をサーバー側で捕捉できない
  • このことから、リクエストを跨いだロック操作は厳禁
    ユーザーが離脱したらロックがいつまで経ってもリリースされなくなる!

これらのことから、Webアプリと悲観ロックは相性が悪い。


そこで楽観ロック

  • 本質的にはロックじゃない
  • レコードにバージョンを持っておく
  • 更新時にバージョンをインクリメント
  • 画面に、操作中のレコードのバージョンを覚えておく
  • 画面から更新するとき、覚えておいたバージョンと一致するときにみ、更新する
    • 実装としては where version = ? とする
  • 一致しない場合はロック獲得失敗と扱う

RDBの楽観ロックサポート

  • SQL ServerのRowVersion型
    • UPDATEすると自動でインクリメントされる
    • Entity Frameworkでは byte[] にするのがポイント

意外と、同等の機能を持つRDBMSは少ないようなので、SQL Server系を使うときは活用したいところ


設計上のポイント

  • 入れ子になっているデータ
    • 子だけ更新する際に、バージョンはどれを参照するのか?
    • 業務仕様によっては、親リソースのバージョンを見る必要がある

Webアプリでも悲観ロックは必要

  • リクエストを跨いでロック保持するのがNGなだけで、同一リクエストの中では適切にロックを取得する必要がある
    • UNIQUE制約を確実に避けながらINSERTする、など

最後に

  • Webアプリは本質的にマルチプロセス
  • 操作を跨ぐロックは楽観ロックを使う
  • 楽観・悲観のどちらか?ではない。適切に組み合わせる
  • ロックを後から設計・実装するのは超大変
  • 最初から考えておきましょう!
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?