楽観ロックとは、「他のユーザーと同時にデータを更新する可能性は低い」という楽観的な前提に基づいた排他制御の方法です。データそのものにロックをかけず、更新処理時にデータが取得時と同じ状態であることを確認することで、データの整合性を保ちます。
例えば、図書館で本の貸出管理を行うシステムを考えましょう。本の在庫を示すカラムを持つ「書籍テーブル」があり、利用者が本を借りる際、この在庫カラムを更新するAPIが実行されます。
ある本の在庫が5冊ある状態で、利用者Aがこの本を2冊借りようとします。このとき、書籍テーブルの在庫は「3冊」になるべきです。しかし、同じタイミングで利用者Bも同じ本を3冊借りようとするとどうなるでしょう?
もし2つのリクエストが並行して処理されると、AとBがそれぞれ貸出処理を始めた時点で在庫は「5冊」と認識されます。結果として、Aが借りた後の在庫を「3冊」、Bが借りた後の在庫を「2冊」として計算してしまい、整合性が崩れる可能性があります。このような事態を避けるために、楽観ロックを用います。
具体的な楽観ロックの実装方法
楽観ロックを実装する方法としては、「更新前後でデータが変化していないかを確認する」ことが一般的です。
上記の例では、以下のような手順をとります:
- APIが貸出処理を始める際、書籍テーブルの在庫カラムの現在の値(例えば「5冊」)を取得。
- 本を借りるリクエストを受けた際、在庫カラムが取得時点と同じ値であることを確認。
- 一致する場合、貸出処理を実行し、在庫を更新。
- 一致しない場合(他の処理によって在庫が変更されていた場合)、エラーを返して処理を中止。
例えば、利用者AとBが同時に貸出リクエストを行った場合、Aが更新処理を完了した後、Bの処理では在庫の整合性が取れなくなるためエラーが返されます。その結果、1回のリクエストのみが成功し、データの整合性が保たれます。