データベースの利用の時、同期問題を解決することは非常に重要な課題です。
多くの人が Optimistic Lock(楽観ロック) と Pessimistic Lock(悲観ロック) について聞いたことがありますが、これら2つのロックの仕組みや適用シナリオについては明確でない場合があるかもしれません。
本記事では、2つロックを紹介し、それぞれの利点と欠点を分析することで、実際のプロジェクトでより良い選択ができるようにします。
Optimistic Lockとは?
Optimistic Lockは、「データを更新する前に、衝突が起こらない」と仮定し、
主に関連性の少なくてアクセス頻度が高いなデータ環境で使用されます
実現手順
- Optimistic Lockは通常、バージョン番号や更新回数のコラムを使用して同期問題を解決:
- データを更新する前に、バージョン番号または更新回数を取得
- レコードを更新する時に、現在のバージョン番号と取得時のバージョン番号を比較
- バージョン番号が一致していない場合、データが他のユーザーに更新されたと判断され、更新失敗になります
実装例
- バージョン番号列を使用した Optimistic Lock の簡単な実装例
-- users テーブルには id, name, version=1 列が含まれているとします。
-- データを取得
SELECT id, name, version FROM users WHERE id = 1;
-- データを更新
UPDATE users
SET name = 'New Name', version = version + 1
WHERE id = 1 AND version = 1;
利点
- データベースのロックを使用しないため、効率が高いです
欠点
- 衝突頻度が高い場合、retry頻度が高くなってスループット低下の問題を起こします
Pessimistic Lockとは?
Pessimistic Lockは、「更新衝突の可能性があるため、他のユーザーがデータを使用しないようにロックする」と仮定します
実現手順
- Pessimistic Lockは通常、データベースのロック機能を使用して実現されます
- データを読み取る時に、当該デーたをロックして他のユーザーが読み取ったり更新したりするのを防ぎます
- 更新が完了した後、ロックを解除
実装例
- ロックを使用したPessimistic Lockの簡単な実装例
-- Transactionを開始
START TRANSACTION;
-- 対象データをロック
-- FOR UPDATE を使用してデータをロックし、他のTransactionが同時にデータを変更するのを防ぎます
SELECT * FROM users WHERE id = 1 FOR UPDATE;
-- データを更新
UPDATE users SET name = 'New Name' WHERE id = 1;
-- コミット
COMMIT;
利点
- データの整合性が確保できます
- よく衝突が多発する環境に使用されます
欠点
- ロックを使用するため、システム負荷が増加します
- ロックが長時間解除されない場合、デッドロックを引き起こす可能性があります
Isolation levelとの関係
データベースのisolation levelは、Optimistic LockとPessimistic Lockの選択や実現方法など直接に影響します
Optimistic LockとIsolation level
Optimistic Lock は、Read CommittedやRead Uncommittedなどの低Isolation levelで効率的に動けます。
これらのIsolation levelは、複数のTransactionが同時にデータを読み取ったり更新したりできて、バージョン管理によって衝突を回避します
-
Read Uncommitted:
未コミットの変更を読み取ることがOKですので、潜在的な衝突を処理する必要があります -
Read Committed:
コミット済みの変更のみを読み取ることを保証し、衝突の発生可能性を減少させます
Pessimistic LockとIsolation level
Pessimistic Lockは、Repeatable ReadやSerializableなどの高Isolation levelの環境で使用されます
-
Repeatable Read:
同一データを複数回読み取る場合に、他のTransactionで変更されたデータを読み取らないことを保証します -
Serializable:
Transactionを完全に隔離し、すべての可能な衝突が回避できます。厳密な整合性が必要な場合に使用されます
Isolation levelの選択ポイント
Optimistic Lockと Pessimistic Lockを選択する際は、下記の4つのポイントを考慮する必要があります:
- 衝突率: 衝突率が低い場合はOptimistic Lockが優先、逆の場合はPessimistic Lockを利用します
- 効率要件: 再試行が許容されない場合は、Pessimistic Lockを利用します
- 整合性: 重要なデータの整合性要件が高い場合は、Pessimistic Lockが優先
- 基盤能力: 最終的には、システムのサポート能力やデータベースの機能が選択に影響を与えることがあります
まとめ
Optimistic LockとPessimistic Lockはそれぞれに利点と欠点があり、その選択は実際のシナリオに基づいて考える必要があって、
ロックモデルについて理解を深めることで、実際のプロジェクトの効率や安定性など向上させることができます。
また、データベースのIsolation levelとの組み合わせにより、柔軟な同期戦略を設計し、多様なニーズに対応することが可能です。