LASSIC Media らしくメディア
楽観ロックと悲観ロックの違い|排他制御
LASSIC IT事業部|元請(プライムベンダー)としてシステム開発・検証を受託
複数の利用者が同じデータへ同時にアクセスするシステムでは、片方の更新がもう片方の更新で上書きされてしまう「更新の競合」が起こり得ます。この競合を防ぐための仕組みを排他制御と呼び、その代表的な実現方式として語られるのが楽観ロックと悲観ロックです。名前は似ていますが、競合への向き合い方はまったく逆を向いています。
本記事では、楽観ロックと悲観ロックという二つの排他制御方式の違いを、仕組み・メリットとデメリット・使い分けの判断軸という観点から整理します。特定のデータベース製品のロック構文には深入りせず、発注担当者・PM・設計者が押さえておきたい「考え方の違い」に焦点を当てて解説します。
この記事のポイント
- 楽観ロックは更新時にバージョンなどの情報を照合して競合を検知する「検知型」、悲観ロックは処理を始める前にロックを確保して他者を待たせる「予約型」という、逆方向の設計思想です。
- 悲観ロックはしっかり競合を防げる一方で待ち時間やデッドロックのリスクを伴い、楽観ロックは待たせない代わりに競合発生時のやり直し処理が必要になります。
- 競合が稀な参照中心の処理では楽観ロック、競合が頻発し確実な排他が求められる処理では悲観ロックというように、データの性質に応じた使い分けが求められます。
目次
排他制御はなぜ必要か(同時更新の競合)
複数の利用者が同時にシステムを操作する環境では、同じレコードを別々の画面から読み込み、それぞれが編集して保存するという状況が日常的に発生します。このとき何の対策も講じていないと、後から保存した側の更新が先に保存した側の更新をそのまま上書きしてしまい、片方の変更内容がなかったことになる恐れがあります。これがいわゆる「更新の競合」であり、いわゆるロストアップデート(更新消失)と呼ばれる問題です。
競合が起こりやすい場面
在庫数量の同時引き当てや、複数担当者が同じ案件情報を並行して編集するワークフロー、予約システムの空き枠確保など、業務システムには競合が起こりやすい場面が多くあります。利用者数が少ない社内システムであっても、同じレコードへの操作が重なるタイミングは意外と存在するものです。
排他制御という考え方
排他制御とは、こうした同時更新による競合を防ぐための仕組み全般を指す言葉です。その実現方法にはいくつかの考え方がありますが、実務でよく比較の対象となるのが、更新時に競合の有無を確認する楽観ロックと、操作を始める前に他者の操作を防いでしまう悲観ロックの二方式です。次の項から、それぞれの仕組みを順に見ていきましょう。
トランザクション分離レベルとは別の話
排他制御を検討していると、トランザクションの分離レベルという言葉が並んで登場することがあります。分離レベルは、一つの処理の途中経過を他の処理からどこまで見えるようにするかを定める設定であり、レコード単位で更新の競合をどう防ぐかを決める楽観ロック・悲観ロックとは着眼点が異なるものです。本記事では分離レベルの詳細には立ち入らず、あくまで更新競合への向き合い方の違いに絞って解説します。
楽観ロックとは(バージョン管理で検知)
楽観ロックは、複数の利用者が同時に同じデータを読み書きしても、実際に競合が発生する頻度はそれほど高くないだろうという前提に立つ方式です。読み取りの段階では他者の操作を制限せず、更新を確定させる直前になって初めて競合が起きていないかを確認します。
仕組み:バージョン番号や更新日時で照合する
具体的には、レコードにバージョン番号や更新日時などの列をあらかじめ用意しておき、読み取り時にその値を保持しておきます。更新を実行する際には、保持しておいた値と現在のレコードの値が一致しているかどうかをあわせて確認し、一致していれば更新を実行したうえでバージョンを進めます。もし一致していなければ、読み取ってから今までの間に別の利用者が先に更新を済ませたということになるため、更新を実行せずにエラーとして扱う流れです。
競合検知後の扱い
競合を検知した場合、システム側はその更新をそのまま失敗として扱い、利用者に対して最新の状態を読み直してから操作をやり直すよう促す設計にするのが一般的です。競合の検知と再試行の案内を、画面設計やアプリケーション側の処理としてどう組み込むかが、楽観ロックを採用する際に検討すべき要点になります。
悲観ロックとは(先にロックを取得)
悲観ロックは、楽観ロックとは逆に、複数の利用者が同時に同じデータへアクセスすれば競合はいずれ起こるものだという前提に立つ方式です。競合が起きてから対処するのではなく、そもそも競合が起きないように、操作を始める段階で他者の操作を制限してしまいます。
仕組み:処理開始時にロックを確保する
悲観ロックでは、対象のレコードを読み取って編集を始めようとする時点で、そのレコードに対するロックを確保します。ロックを確保している間、他の利用者が同じレコードを更新しようとすると、先に確保されているロックが解放されるまで処理を待たされる仕組みです。ロックを確保した側が更新を終えてロックを解放すると、待っていた次の利用者がロックを確保できるようになり、順番に処理が進んでいきます。
待ち行列としての振る舞い
この方式では、同じレコードへの操作は事実上一つずつ順番に処理される形になるため、更新の競合そのものは発生しません。その代わり、後から来た利用者は前の利用者の処理が終わるまで待たされることになり、待ち時間がどの程度発生するかが実務上の関心事になります。
両者の違い:対比表とフロー図
楽観ロックと悲観ロックは、どちらも同時更新による競合を防ぐという目的は共通していますが、競合への対処のタイミングと考え方が正反対です。主な観点を次の表に整理します。
| 観点 | 楽観ロック | 悲観ロック |
|---|---|---|
| 基本の考え方 | 競合は稀という前提の検知型 | 競合は起こるという前提の予約型 |
| 競合を確認するタイミング | 更新を確定する直前 | 処理を始める前 |
| 他の利用者への影響 | 待たせず並行して読み書きできる | ロック解放まで待たされる |
| 競合発生時の扱い | 更新エラーとし再読み込み・再試行を促す | そもそも競合が発生しない |
| デッドロックのリスク | ロック待ちがないため生じにくい | ロックの取得順によっては生じ得る |
| 実装の手間 | バージョン列とエラー時の再試行処理が必要 | ロックの取得・解放・待ち時間の制御が必要 |
| 向いている場面 | 競合が稀で参照が多い処理 | 競合が多く確実な排他が求められる処理 |
対比表からわかるとおり、楽観ロックと悲観ロックはどちらか一方が常に優れているという関係ではなく、競合をいつ・どう扱うかというトレードオフの違いです。次の図で、二人の利用者が同じレコードを同時に更新しようとした場合の流れの違いを確認しておきましょう。
メリットとデメリット
楽観ロックと悲観ロックは、それぞれに得意な点と注意すべき点を持っています。実際の設計では、次のような観点から両者のバランスを検討することになります。
楽観ロックのメリットとデメリット
- メリット:読み取り時に他者を待たせないため、参照が多く更新が比較的少ない処理では全体の応答性を保ちやすくなります。
- メリット:ロックの取得・解放を管理する必要がなく、デッドロックの心配をあまりせずに実装できる場合が多いです。
- デメリット:競合が発生すると更新が失敗するため、利用者に再試行してもらう画面設計やエラーメッセージの用意が必要になります。
- デメリット:競合の発生頻度が高い処理に採用すると、利用者が何度も再試行を強いられ、体験が悪化する恐れがあります。
悲観ロックのメリットとデメリット
- メリット:ロックを確保している間は他者の更新を防げるため、競合そのものが発生せず処理を安定して完了させやすくなります。
- メリット:在庫の引き当てのように、確実な排他が業務上求められる処理と相性がよい方式です。
- デメリット:ロックを待つ利用者が発生するため、ロックを保持する時間が長い処理では待ち時間が業務上の課題になり得ます。
- デメリット:複数のレコードに対してロックを取得する順序が処理ごとにばらばらだと、互いに相手のロック解放を待ち続けるデッドロックが生じる恐れがあります。
このように、悲観ロックが常に万全というわけでも、楽観ロックが常に軽量で望ましいというわけでもありません。競合の起きやすさと、待たせることが許容できるかどうかを踏まえて判断する必要があるでしょう。
使い分けの判断軸(ユースケース別)
楽観ロックと悲観ロックのどちらに寄せるべきかは、次のような判断軸を確認すると整理しやすくなります。
- 競合の発生頻度――同じレコードへのアクセスが同時に重なる場面がどの程度想定されるか
- 処理の確実性の要件――在庫や与信枠のように、一つずつしか処理を通したくない業務かどうか
- 待ち時間の許容度――利用者に処理を待たせることが業務上受け入れられるか
- 処理時間の長さ――ロックを保持する処理が短時間で終わるか、長時間かかる可能性があるか
- やり直しのしやすさ――競合時に利用者へ再入力・再試行を求めても業務上支障がないか
楽観ロックが向く場面
マスタ情報の編集画面や、更新自体はまれにしか発生しないが参照は頻繁に行われる管理画面などは、楽観ロックとの相性がよい場面です。競合が起きたとしても再読み込みして編集し直せば済む業務であれば、待たせない設計のメリットを活かしやすいでしょう。
悲観ロックが向く場面
在庫数の引き当てや座席・予約枠の確保、口座残高の増減処理のように、二重に処理が通ってしまうと業務上の実害につながる場面では、悲観ロックによって一つずつ順に処理する設計が選ばれやすくなります。ロックを保持する処理を短くまとめ、待ち時間を最小限に抑える工夫とあわせて検討することが多いです。
併用というアプローチ
一つのシステムであっても、すべての処理を同じ方式で統一する必要はありません。マスタ編集など競合が稀な処理には楽観ロックを、在庫の引き当てなど確実性が求められる処理には悲観ロックをというように、処理の性質ごとに方式を選び分けて組み合わせる設計は、実務でも珍しくないアプローチです。どの処理にどちらの方式を採用したかを一覧化しておくと、後から仕様を振り返る際にも見通しがよくなるでしょう。
設計・発注時の確認点
排他制御の方式を発注する際は、次のような点をあらかじめ確認しておくと、後の手戻りを抑えやすくなります。
- 対象の業務データごとに、競合の発生頻度がどの程度見込まれるか整理されているか
- 楽観ロックを採用する箇所で、競合発生時のエラー表示・再試行の画面設計まで含まれているか
- 悲観ロックを採用する箇所で、ロックを保持する処理範囲と想定される待ち時間が説明されているか
- デッドロックが起こり得る処理について、ロック取得順の統一などの対策が検討されているか
- 負荷試験の段階で、同時アクセスを想定した競合・待ち時間の検証が計画に含まれているか
排他制御の方式は、いったん実装した後に途中で切り替えるとなると、周辺のエラー処理や画面設計まで見直しが及びやすい部分です。発注段階でこうした確認点を共有しておくことが、期待とのズレを防ぐことにつながるでしょう。
まとめ:競合の起きやすさで方式を選ぶ
本記事では、排他制御の代表的な二方式である楽観ロックと悲観ロックの違いについて、仕組み・メリットとデメリット・使い分けの観点から整理しました。楽観ロックは更新時にバージョンなどを照合して競合を検知する方式、悲観ロックは処理の前にロックを確保して競合そのものを防ぐ方式であり、競合への向き合い方が逆を向いています。
設計にあたっては、競合の発生頻度・処理の確実性の要件・待ち時間の許容度・処理時間の長さ・やり直しのしやすさといった判断軸を確認し、業務データの性質に応じて楽観ロックと悲観ロックを使い分ける、あるいは同じシステムの中で処理ごとに組み合わせることが、無理のない排他制御の設計につながるでしょう。
よくある質問
楽観ロックと悲観ロックはどちらを選ぶべきですか。
どちらか一方が常に優れているという関係ではありません。競合の発生頻度が低く参照が中心の処理には楽観ロック、競合が多く確実な排他が求められる処理には悲観ロックというように、扱うデータの性質や業務要件に応じて選ぶのが基本です。両方を処理ごとに使い分けるシステムも珍しくありません。
デッドロックとは何ですか。
複数の処理が互いに相手の確保しているロックの解放を待ち続け、どちらも先に進めなくなってしまう状態を指します。悲観ロックで複数のレコードを扱う際に、ロックを取得する順序が処理ごとにばらばらだと発生しやすくなるため、取得順を統一するなどの対策が検討されます。
楽観ロックのバージョン管理は具体的に何を用意すればよいですか。
代表的には、レコードにバージョン番号や更新日時を保持する列を用意し、更新のたびにその値を進める形が用いられます。更新時には、読み取り時に保持していた値と現在の値を照合し、一致していれば更新を実行し、一致していなければ競合として扱う流れです。
悲観ロックを使えば競合を防げますか。
同じレコードに対するロックの仕組みが正しく機能している範囲では、競合そのものは発生しません。ただし、ロックを保持する時間が長引くと他の利用者を長く待たせることになり、ロックの取得順によってはデッドロックが生じる恐れもあるため、常に万能な対策とは言い切れない点に注意が必要です。
楽観ロックで競合が起きたとき、利用者にはどう案内すればよいですか。
更新が競合により失敗したことを伝えたうえで、最新の状態を読み直してから再度編集してもらう案内が一般的です。せっかく入力した内容が失われないよう、入力途中の内容を一時的に保持しておく工夫とあわせて画面設計を検討するとよいでしょう。
楽観ロックと悲観ロックは同じシステムの中で併用できますか。
併用は可能です。参照が多く競合の少ないマスタ編集画面には楽観ロックを、在庫の引き当てなど確実な排他が求められる処理には悲観ロックを採用するというように、処理の性質ごとに方式を使い分ける設計は実務でもよく見られます。
著者:テレリモ総研編集部 鈴木 亮佑
ご不明な点はお問い合わせフォームからもご連絡いただけます。
- *1 出典:IPA(独立行政法人情報処理推進機構)「情報処理技術者試験」シラバスにおける排他制御・同時実行制御関連の情報(https://www.ipa.go.jp/shiken/)