인프런 커뮤니티 질문&답변

범수님의 프로필 이미지
범수

작성한 질문수

재고시스템으로 알아보는 동시성이슈 해결방법

pessimistic lock 관련 질문입니다.

작성

·

1K

0

pessimistic lock을 구현하실때 PessimisticLockStockService 클래스의 decrease 메소드에 @Transactional을 붙이셨는데 이유를 알 수 있을까요?

저는 @Transcational 어노테이션을 decrease 메소드에 붙이지 않으면 실행시
org.springframework.dao.InvalidDataAccessApiUsageException: no transaction is in progress; nested exception is javax.persistence.TransactionRequiredException: no transaction is in progress
이런 에러가 발생합니다. 해당 어노테이션을 찾아는 봤는데 pessimistic lock을 메소드에 걸었을때 transactional을 걸어야한다 이런 자료는 찾지 못해서요. 답변 부탁드립니다. 감사합니다.

 

참고로 @Transactional 어노테이션을 걸어주지 않으면 아래 사진처럼 quantity가 하나도 감소하지않은 100개가 결과값으로 출력됩니다.

답변 2

0

최상용님의 프로필 이미지
최상용
지식공유자

범수님 안녕하세요.

일단 트랜잭션이 없을때 에러가 나는이유는 스크린샷에서 보실 수 있는 hibernate 의 스펙입니다.

image

이러한 스펙이 있는 저의 개인적인 생각을 말씀드리겠습니다.

select for update 쿼리를 사용하여 데이터를 가지고 오는것은 데이터를 업데이트 하기 위함입니다.

select for update 는 Transaction 단위로 묶이기때문에 트랜잭션을 사용하지 않았을 때 select for update 를 사용하는 의미가 없어집니다.

그 이유는 아래와 같습니다.

public void decrease() {
   select for update // lock 을 잡으며 데이터를 가져옴
   // 트랜잭션이 없기때문에 (종료되었기때문에) lock 이 풀립니다.
   update()
}

이러한 이유로 저러한 스펙이 추가된것이라고 생각합니다.

 

추가적으로 궁금한게 있으시다면 질문 부탁드리겠습니다!

0

범수님의 프로필 이미지
범수
질문자

제가 추측한 이유로는

우선 @Tracnsactional 어노테이션은 해당 메소드에 걸 경우 메소드가 실패시 메소드에서 실행했던것들을 롤백, 성공시 커밋을 함으로써 서비스를 하나의 트랜잭션으로 묶는 어노테이션으로 알고있습니다.

pessimistic lock을 걸 경우에는 해당 데이터에 락을 걸어 자원을 사용하고 있을경우 대기를 한다고 하셨는데요.

이 대기를 하는 작업이 transaction에서 실패로 인식하나? 그래서 작업이 롤백되는건가 해서 찾아봤는데 명확한 원인을 찾기 힘들어서요.

소스코드가 필요하실까봐 깃허브 주소도 업로드해두겠습니다.

https://github.com/xanqus/spring-concurrency-problem_exam

답변 기다리고있겠습니다!

범수님의 프로필 이미지
범수

작성한 질문수

질문하기