비관적 락과 낙관적 락의 차이점
비관적 락(Pessimistic Lock)과 낙관적 락(Optimistic Lock)은 동시성 제어(Concurrency Control) 를 위해 사용되는 두 가지 대표적인 방식입니다.
1. 비관적 락(Pessimistic Lock)
비관적 락은 데이터를 수정하는 동안 다른 트랜잭션이 해당 데이터를 변경하지 못하도록 차단하는 방식입니다. 즉, 트랜잭션이 시작되면 즉시 잠금을 걸고, 트랜잭션이 종료될 때까지 다른 트랜잭션이 접근할 수 없도록 하는 방식입니다.
특징
✅ 장점
• 경쟁이 심한 환경에서도 안전하게 데이터 정합성을 보장할 수 있습니다.
• 동시성 충돌이 발생할 가능성이 높은 경우 적합합니다.
❌ 단점
• 잠금이 유지되는 동안 다른 트랜잭션이 대기해야 하므로 성능 저하가 발생할 수 있습니다.
• 데드락(Deadlock) 위험이 있습니다.
JPA에서 비관적 락 사용 예시
JPA에서 비관적 락을 사용하려면 @Lock 어노테이션을 이용하면 됩니다.
import jakarta.persistence.LockModeType;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Lock;
import java.util.Optional;
public interface ProductRepository extends JpaRepository<Product, Long> {
@Lock(LockModeType.PESSIMISTIC_WRITE) // 비관적 쓰기 락 적용
Optional<Product> findById(Long id);
}
위 코드에서 @Lock(LockModeType.PESSIMISTIC_WRITE)을 설정하면,
해당 데이터를 조회할 때 쓰기 락(PESSIMISTIC_WRITE) 이 걸려 다른 트랜잭션에서 해당 데이터를 변경하지 못하도록 막습니다.
2. 낙관적 락(Optimistic Lock)
낙관적 락은 데이터에 잠금을 걸지 않고 트랜잭션이 완료될 때 충돌이 있는지 확인하는 방식입니다.
즉, 트랜잭션이 끝날 때까지 다른 트랜잭션이 데이터를 변경하지 않았다고 가정하고 작업을 수행한 후,
커밋 시점에 충돌을 검출하고 롤백 처리합니다.
특징
✅ 장점
• 데이터 충돌이 자주 발생하지 않는 경우 성능이 뛰어납니다.
• 락을 걸지 않으므로 데드락이 발생하지 않습니다.
❌ 단점
• 동시에 여러 트랜잭션이 같은 데이터를 수정하려고 할 경우 충돌이 발생할 가능성이 높습니다.
• 충돌이 발생하면 트랜잭션이 롤백되므로 재시도 로직이 필요할 수 있습니다.
JPA에서 낙관적 락 사용 예시
JPA에서는 @Version 어노테이션을 이용해 낙관적 락을 적용할 수 있습니다.
import jakarta.persistence.*;
@Entity
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private int stock;
@Version // 낙관적 락을 위한 버전 필드
private int version;
// Getter, Setter 생략
}
그리고 Repository에서 데이터를 수정할 때는 @Version 필드를 자동으로 활용하여 충돌을 감지합니다.
@Service
public class ProductService {
@Autowired
private ProductRepository productRepository;
@Transactional
public void updateStock(Long productId, int quantity) {
Product product = productRepository.findById(productId)
.orElseThrow(() -> new RuntimeException("상품을 찾을 수 없습니다."));
product.setStock(product.getStock() - quantity);
productRepository.save(product);
}
}
낙관적 락의 동작 방식
1. 데이터 조회 시 version 값을 함께 가져옵니다.
2. 트랜잭션이 끝날 때 version 값을 비교합니다.
• 트랜잭션이 시작될 때 읽은 version 값과, 커밋 시점의 version 값이 동일하면 정상적으로 업데이트 수행
• 다른 트랜잭션이 먼저 값을 변경하여 version 값이 바뀌었다면, 예외(OptimisticLockException) 발생 및 롤백
비관적 락 vs 낙관적 락 비교 정리
비관적 락 (Pessimistic Lock)낙관적 락 (Optimistic Lock)
잠금 방식 | 트랜잭션이 시작될 때 즉시 잠금 | 잠금 없이 트랜잭션 종료 시 충돌 확인 |
경쟁 환경 | 경쟁이 심한 환경에서 적합 | 경쟁이 적은 환경에서 적합 |
데드락 위험 | 있음 | 없음 |
성능 | 동시성이 낮아 성능 저하 가능 | 동시성이 높아 성능 우수 |
충돌 발생 시 | 충돌 방지 가능 | 충돌 발생 시 예외 발생 및 롤백 |
비관적 락 vs 낙관적 락 선택 기준
• 경쟁이 빈번한 환경 (e.g., 은행 시스템, 재고 관리 등) ➝ 비관적 락
• 경쟁이 적고 성능이 중요한 경우 (e.g., 읽기 요청이 많고 쓰기 충돌이 드문 경우) ➝ 낙관적 락
실제 활용 예시
1. 비관적 락 적용 예시
• 동시에 많은 사용자가 같은 데이터를 수정할 가능성이 높은 경우
• 예: 온라인 쇼핑몰에서 “한정 수량” 상품 구매 처리
2. 낙관적 락 적용 예시
• 대부분 읽기 위주이며, 가끔 업데이트가 발생하는 경우
• 예: 게시판 댓글 수정, 사용자의 프로필 정보 변경
결론
• 비관적 락은 강력한 데이터 일관성을 보장하지만 성능 저하가 우려됨.
• 낙관적 락은 충돌이 자주 발생하지 않는 환경에서 유리하며 성능이 뛰어남.
• 상황에 따라 적절한 방법을 선택하는 것이 중요!
'면접 준비 > DB' 카테고리의 다른 글
[DB] PhantomRead란? (0) | 2025.03.02 |
---|---|
[DB / Transaction] 트랜잭션 고립 수준 (0) | 2025.03.02 |
[CS 면접 질문 - DB] 파티셔닝 (0) | 2025.01.06 |
[CS 개념 정리 - DB] 정규화 (1) | 2025.01.06 |
[CS 개념 정리 - DB] 인덱스 (0) | 2025.01.06 |