낙관적 락과 비관적 락은 여러 트랜잭션이 같은 데이터를 수정할 때 갱신 유실을 방지하기 위한 동시성 제어 방식입니다.

낙관적 락은 충돌이 자주 발생하지 않을 것이라고 가정하고, 데이터를 읽을 때 DB 레벨에서의 물리적인 락을 걸지 않는 것입니다. 대신 수정 시점에 버전이 읽었을 때와 같은지 확인합니다. JPA에서는 엔티티에 @Version 필드를 두며, UPDATE의 조건에 식별자와 버전을 함께 사용합니다. 영향을 받은 행이 없다면 다른 트랜잭션이 먼저 수정한 것이므로 예외를 발생시킵니다.

@Version
private Long version;

충돌이 적고 읽기가 많은 환경에서는 동시성이 높지만, 충돌이 발생하면 사용자에게 알리거나 안전하게 재시도하는 로직이 필요합니다.

비관적 락은 충돌이 발생할 가능성이 높다고 보고 데이터를 읽는 시점부터 데이터베이스 잠금을 획득합니다. JPA의 PESSIMISTIC_WRITE는 일반적으로 SELECT ... FOR UPDATE 같은 잠금 조회로 변환되어 다른 트랜잭션의 수정을 대기시킵니다.

@Lock(LockModeType.PESSIMISTIC_WRITE)
Optional<Stock> findById(Long id);

충돌이 잦고 반드시 순서대로 처리해야 하는 재고 차감 등에 유용하지만, 잠금 대기와 타임아웃, 교착 상태가 발생할 수 있습니다. 따라서 충돌 빈도, 재시도 비용, 응답 시간 요구사항을 기준으로 선택해야 합니다.

출처 및 참고자료

CS 면접 대비 (DB 편) - 2.2 [꼬리 질문] 낙관적 락과 비관적 락의 차이를 설명해주세요. ⭐️⭐️⭐️📙 JSCODE 박재성 📙✔️ https://linktr.ee/jscode📗 프로그래밍 무료 강의 📗✔️ https://www.youtube.com/@jscode-official/playlistswww.youtube.com