楽観ロック
楽観ロックは、データ更新時に競合「きょうごう」があまり発生しないことを前提としています。
バージョン番号を使用してデータの一貫性を確保します。
実行順番
- テーブルから目標データを取得する
Product product = productRepository.findById(productId);
- データの存在を確認する
if (product == null) {
throw new RuntimeException("Product not found");
}
- データを更新する
product.setQuantity(newQuantity);
4.保存時にバージョン番号をチェックする
productRepository.save(product);
try {
productRepository.save(product);
} catch (OptimisticLockingFailureException e) {
retryUpdate(productId, newQuantity);
}
悲観ロック
悲観ロックは、データ更新時に競合が頻繁に発生することを前提としています。
データをロックし、他のトランザクションが変更するのを防ぎます。
実行順番
- トランザクションを開始する
@Transactional
2.データをロックする、悲観ロック(PESSIMISTIC_WRITEモード)を使用して、他のトランザクションからの変更を防ぎます。
Product product = entityManager.find(Product.class, productId, LockModeType.PESSIMISTIC_WRITE);
- トランザクション内で安全にデータを更新する
product.setQuantity(newQuantity);
まとめ
楽観ロック:
データ更新の競合が少ない場合に適しています。バージョン番号を利用し、不一致があれば例外をスローして再試行します。主にシステムのパフォーマンスを重視する場面で使われます。
悲観ロック:
データ更新の競合が頻発する場合に適しています。データを明示的にロックし、他のトランザクションによる変更を防ぎます。一貫性を重視するシステムで効果的です。
選択基準:
データ競合の頻度が低い → 楽観ロック
データ競合の頻度が高い → 悲観ロック