작성
·
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 의 스펙입니다.
이러한 스펙이 있는 저의 개인적인 생각을 말씀드리겠습니다.
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
답변 기다리고있겠습니다!