인프런 커뮤니티 질문&답변
비관적 락 구현 방식 문의 건
작성
·
34
·
수정됨
0
1. 현재 학습 진도
몇 챕터/몇 강을 수강 중이신가요?
여기까지 이해하신 내용은 무엇인가요?
강사님 안녕하세요 :)
현재 4-9 낙관적 락, 비관적 락 강의를 수강하는 중이며,
단일 행에 대해 배타 락을 거는 방식을 학습한 후 관련 문의 드립니다.
2. 어려움을 겪는 부분
어느 부분에서 막히셨나요?
코드의 어떤 로직이 이해가 안 되시나요?
어떤 개념이 헷갈리시나요?
만약비관적 락(PESSIMISTIC_WRITE) 방식으로 한 테이블의 여러 행에 락을 걸어야 한다면,
아래 두 방식 중 어느 방식이 적절한지 궁금합니다.
N번의 DB 조회를 방지하기 위해 아래 1번 방식을 고려했으나,관련 케이스가 많지 않아 제가 놓치는 부분이 있는지 여쭤보고 싶습니다.
더불어 실무에서는 어떤 방식으로 접근하시는지도 궁금합니다. :)
3. 시도해보신 내용
문제 해결을 위해 어떤 시도를 해보셨나요?
에러가 발생했다면 어떤 에러인가요?
현재 작성하신 코드를 공유해주세요
1. IN절 조회 후 락 걸기@Lock(LockModeType.PESSIMISTIC_WRITE)
@Query("select p from Product p where p.productNumber in :productNumbers")
List<Product> findAllByProductNumberIn(@Param("productNumbers") List<String> productNumbers);만약 1번 방식이 적절하다면, 데드락 방지를 위해 ORDER BY 정렬이 필수인지 궁금합니다.
2. 루프를 돌며 조회 후 락 걸기
for (String productNumber : productNumbers) { Product product = productRepository.findByProductNumberWithLock(productNumber) .orElseThrow( ··· ); ··· }
@Lock(LockModeType.PESSIMISTIC_WRITE)@Query("SELECT p FROM Product p WHERE p.productNumber = :productNumber")
Optional<Product> findByProductNumberWithLock(@Param("productNumber") String productNumber);
이렇게 구체적으로 알려주시면, 더 정확하고 도움이 되는 답변을 드릴 수 있습니다!
답변 1
0
안녕하세요, 인프런 AI 인턴입니다. shsf님.
비관적 락을 구현하는 방식에 대해 고민하고 계신 질문에 대해 답변 드리겠습니다. 비관적 락(PESSIMISTIC_WRITE)을 사용할 때, 특히 여러 데이터 행에 대해서 락을 걸어야 할 경우의 접근 방식에 대해서 설명드립니다.
1. IN절 조회 후 락 걸기
이 방법은 현명한 선택일 수 있습니다. 데이터베이스 쿼리에 IN 절을 사용하여 여러 행을 한꺼번에 락을 걸 수 있어, 여러 번의 DB 접근을 최소화할 수 있습니다. 주의할 점은 데드락 방지를 위해 ORDER BY 절을 추가하여 정렬된 방식으로 데이터를 처리함으로써 충돌 가능성을 줄일 수 있습니다. 데이터가 있는 테이블의 성능에 따라 ORDER BY가 성능에 영향을 줄 수 있으므로 이 점을 고려하면 좋습니다.
@Lock(LockModeType.PESSIMISTIC_WRITE)
@Query("select p from Product p where p.productNumber in :productNumbers order by p.productNumber")
List<Product> findAllByProductNumberIn(@Param("productNumbers") List<String> productNumbers);
2. 루프를 돌며 조회 후 락 걸기
이 방식은 각 개별 행을 락으로 보호하므로, 세밀하게 제어할 수 있습니다. 특정 행에서 문제가 생길 경우에만 반복 흐름을 제어할 수 있게 됩니다. 하지만 각각의 조회가 트랜잭션으로 관리되어야 하고, 트랜잭션 경계 간의 적절한 관리가 필요합니다. 특히 다수의 트랜잭션을 생성할 경우, 자원 소모가 클 수 있어 성능 비용이 증가할 수 있습니다.
for (String productNumber : productNumbers) {
Product product = productRepository.findByProductNumberWithLock(productNumber)
.orElseThrow(() -> new RuntimeException("Product not found"));
// 추가 로직
}
실무에서의 접근 방법
대규모 데이터베이스 환경에서는 IN절을 활용한 방법으로 가능한 한 서버 쪽의 거래 비용을 줄이는 방법을 많이 사용합니다. 동시에 행을 선택하고 트랜잭션을 관리하기 때문에 성능상의 이점이 있습니다. 그러나, 데이터 동시 액세스가 매우 빠르게 일어나는 환경에서는 오히려 트랜잭션보다 낙관적 락이나 다른 동시성 제어 메커니즘을 고려하기도 합니다.
관련하여 추가적인 상황이나 테스트 환경에서 어떻게 구현되는지 이해하기 위해 몇 가지 실제 사례나 질문에 대해서 더 알아보고 싶다면, 유사한 비관적 락 구현 사례와 실무 적용 방법에 대한 자료를 참조하여 보시길 추천드립니다.
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.




