「排他制御」は主にデータベースに関する文脈で使われる用語で、同じデータを複数のユーザーやプロセスが同時に変更しようとしたときに起こる問題を防ぐための仕組みです。例えば2人が同じドキュメントを同時に編集しようとすると、変更が競合してデータが壊れてしまいますよね。これを避けるために用いられるのが排他制御で、適切な排他制御を導入することで安全なデータベース利用が可能になります。
ザックリいえば、同時に複数の人が同じデータに対して更新をしないようにデータにロックをかけましょう!ということです。
排他制御は大きく以下の2通りあります。ここではそれぞれどのような仕組みで排他制御を実現しているのか?という観点で1からわかりやすく初心者向けにご説明します。
ロックの種類 | 説明 | 適用場面 |
---|---|---|
楽観ロック (Optimistic Locking) | データの競合が少ないと仮定し、データの読み取りと書き込みの間にロックをかけず、更新時に競合が発生した場合にのみ処理をリトライする方法。 | データの更新が比較的少なく、読み取りが多いシナリオ |
悲観ロック (Pessimistic Locking) | データの競合が発生する可能性が高いと仮定し、データの読み取り時点でロックをかけて、他のトランザクションがそのデータにアクセスできないようにする方法。 | 競合が頻繁に発生するシナリオや、データの一貫性が非常に重要な場面 |
楽観ロック (Optimistic Locking) とは?
楽観ロックは、「他の人が同時にデータを使うことは少ないだろう」と考えてデータを扱う方法です。簡単に言うと、楽観ロックはデータの変更が同時に起きることをあまり心配せずに進めるけど、最後に問題がないかチェックする仕組みです。
楽観ロックの動作原理
- データの読み取り
- まず、データを読み取るときにそのデータのバージョンや変更された時間を記録します。これは「データがこの時点でどうなっているか」を覚えておくためです。
- データの変更
- 次に、データを変更します。この時点では他の誰かも同じデータを変更しているかもしれないと考えますが、気にせずに変更を進めます。
- データの更新前のチェック
- データをデータベースに保存する前に、最初に記録したバージョンや変更された時間と、現在のデータのバージョンや時間を比べます。
- バージョンが同じ→他の誰もその間にデータを変更していないことが確認できるので、変更を保存。
- バージョンが異なる→他の誰かがそのデータを変更したことが分かるので、今回の変更は失敗とみなします。再度データを読み取り直して、もう一度最初からやり直し。
- データをデータベースに保存する前に、最初に記録したバージョンや変更された時間と、現在のデータのバージョンや時間を比べます。
楽観ロックの具体例
シナリオ オンラインショッピング
背景: オンラインショッピングサイトで商品を購入する場合を考えます。このサイトでは在庫管理のために楽観ロックを使っていることとします。
- データの読み取り
- あなたがサイトにアクセスして、欲しい商品を選択。この時点で在庫情報が10個存在することと現在の時間を記録しておきます。
- データの変更
- 商品をカートに入れ、購入手続きを進めます。(クレジットカード情報を入力し配送先の確認などを行うイメージ。)この間、他のユーザーも同じ商品を購入しようとしていますが、あなたは特に気にせず手続きを進めます。
- データの更新前のチェック
- 最後に「購入」ボタンを押したときにシステムで再度在庫を確認します。
- 在庫がまだ10個ある場合→システムは他の誰もこの商品を購入していないことを確認。これにより、あなたの購入手続きを完了し、「購入が成功しました」と表示。
- 在庫が変わっている場合(例えば、8個に減っている場合)→システムは、他の誰かがその間に商品を購入したことを検出します。この場合、システムは「在庫が不足しています」と表示し、あなたの購入手続きをやり直すように求めます。
- 最後に「購入」ボタンを押したときにシステムで再度在庫を確認します。
このように楽観ロックは、データの競合が少ないことを前提として処理を進め、最後に一貫性を確認する方法です。システムはデータの更新時にだけ問題をチェックするので、全体的なパフォーマンスが向上しますが、競合が発生した場合には再試行が必要となるデメリットがあります。
悲観ロック (Pessimistic Locking) とは?
悲観ロックは、「他の人が同時にデータを使う可能性が高いから、今使っている間は他の人が触らないようにしよう」と考えてデータを扱う方法です。簡単に言うと、悲観ロックはデータを使うときにしっかりと鍵をかけて、誰もそのデータに触れないようにする仕組みです。
悲観ロックの動作原理
- データの読み取り時にロックをかける
- データを読み取るときに、そのデータに「鍵」をかけます。これにより、他の人はそのデータを使えなくなります。
- データの変更
- 鍵をかけた状態でデータを変更。誰もそのデータにアクセスできないので、安心して変更可能。
- トランザクションの終了
- 変更が終わり、トランザクションが完了したら鍵を外す。→これで他の人が再びそのデータを使えるようになる。
参考 トランザクションとは?
悲観ロックの具体例
シナリオ オンラインデータベースのレコード編集
- データの読み取り時にロックをかける
- 会社のデータベースで顧客情報を編集しようとする場合に悲観ロックを採用しているとします。この場合顧客情報を読み取ると同時にその情報にロックをかけます。これにより、他の社員はその顧客情報を編集できなくなります。
- データの変更
- 顧客情報を更新します(例えば、住所を変更したり連絡先を追加したり)。この間、他の社員はその顧客情報を編集しようとすると、「他の人が編集中です」と表示され、待つことになります。
- トランザクションの終了
- あなたが編集を終えて変更を保存します。すると、ロックが解除され、他の社員もその顧客情報を編集できるようになります。
このように悲観ロックはデータを使っている間に他の人がそのデータにアクセスできないようにする方法です。データの競合が頻繁に発生する場合や、データの一貫性が非常に重要な場合に使われます。
まとめ 悲観ロックと楽観ロックの違い
ロックの種類 | 説明 | 適用場面 |
---|---|---|
楽観ロック (Optimistic Locking) | データの競合が少ないと仮定し、データの読み取りと書き込みの間にロックをかけず、更新時に競合が発生した場合にのみ処理をリトライする方法。 | データの更新が比較的少なく、読み取りが多いシナリオ |
悲観ロック (Pessimistic Locking) | データの競合が発生する可能性が高いと仮定し、データの読み取り時点でロックをかけて、他のトランザクションがそのデータにアクセスできないようにする方法。 | 競合が頻繁に発生するシナリオや、データの一貫性が非常に重要な場面 |