낙관적 락과 비관적 락

1. 낙관적 락 (Optimistic Lock)

충돌이 자주 발생하지 않는다고 가정하고, 데이터를 갱신할 때 충돌을 감지하여 처리하는 방식

 

동작 방식

  1. 데이터를 조회할 때 특정 버전 정보를 함께 가져옴
  2. 업데이트할 때 기존 버전과 비교하여 변경되지 않았으면 업데이트
  3. 버전이 다르다면 충돌이 발생한 것으로 생각하고, 갱신 실패 처리 후 재시도 또는 오류 반환

장점

  • 동시성이 높은 환경에서 성능이 좋음 (락을 걸지 않으므로 대기 시간이 없다)
  • 데드락 발생 가능성 X

단점

  • 충돌이 자주 발생하면 성능 저하
  • 충돌 감지를 위한 추가 로직 필요

사용 예시

 

@Entity
public class Product {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @Version  // 낙관적 락을 위한 버전 관리
    private Integer version;
    
    private int stock;
    
}

 

 

2. 비관적 락 (Pessimistic Lock)

충돌이 발생할 가능성이 높다고 가정하고, 데이터를 갱신할 때 미리 락을 걸어 다른 트랜잭션이 접근하지 못하도록 하는 방식

 

동작 방식

  1. 데이터를 조회할 때 락을 설정
  2. 해당 데이터에 대한 수정 작업을 완료할 때까지 다른 트랜잭션이 접근 불가
  3. 트랜잭션이 종료되면 락이 해제됨

장점

  • 동시 수정 충돌을 원천 차단하여 안정성 보장
  • 충돌이 자주 발생하는 경우에도 일관성을 유지하기 쉬움

단점

  • 락을 유지하는 동안 다른 트랜잭션이 대기하니까 성능 저하 가능
  • 데드락 발생 가능성

사용 예시

@Lock(LockModeType.PESSIMISTIC_WRITE)
@Query("SELECT p FROM Product p WHERE p.id = :id")
Product findByIdWithLock(@Param("id") Long id);

 

 

정리

 

동시 수정 충돌이 많을거 같으면 -> 비관적 락

동시 수정 충돌이 적을거 같으면 -> 낙관적 락

대기 시간이 중요한 경우 -> 낙관적 락

데이터 정합성이 중요한 경우 -> 비관적 락