inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

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

Optimistic Lock 활용해보기

OptimisticLockStockService에서 @Transactional을 붙이게 되면 무한루프에 빠지는 이유 질문

445

요니

작성한 질문수 41

0

안녕하세요 강사님.
강사님 강의를 예전에 들었는데 ,
현업에서 실제 동시성 처리를 하려고 다시 보니
예전에 안보이던게 보이는 것 같습니다. 감사합니다.

제가 질문하고 싶은 부분은
강의를 들으면서 습관적으로
OptimisticLockStockService에서 @Transactional을 붙였는데 무한루프에 빠졌습니다.

앞의 질문에 대한 답변으로 강사님이 보내주신
답변을 힌트로 그 원인을 생각했는데 ,
이부분에 대해 피드백을 주시면 감사하겠습니다.

제가 이해한 바로는 OptimisticLockStockFacade에
@Transactional을 붙이게 되면,
트랜잭션이 재시도 로직을 포함해서 묶이면서,
version 차이로 재시도를 할 때 새로운 버전으로 Stock을
조회해와야 하는데,
아직 Transactional이 유지되고 있으니깐,
Entity Manager에 있는 이전에 실패한 version의 Stock을 가지고 다시 update를 실패해서
무한루프에 빠진다고 생각했습니다.

java spring 동시성

답변 2

0

최상용

요니님 안녕하세요!
생각하신 원인이 맞습니다!

0

인프런 AI 인턴

안녕하세요, 인프런 AI 인턴입니다. 요니님의 질문에 대해 도움을 드리고자 합니다.

요니님께서 말씀하신 낙관적 락(OptimisticLock)과 관련된 트랜잭션 처리에서 무한 루프에 빠지는 문제는, 트랜잭션 범위와 재시도 로직이 연관된 것으로 이해해 주셔야 합니다. 특히, 낙관적 락을 사용할 때 @Transactional 어노테이션의 적용 범위는 매우 중요합니다.

일반적으로 낙관적 락은 동시성을 관리하기 위해 데이터의 버전을 확인하며, 트랜잭션이 성공적으로 데이터를 업데이트하면 버전 번호가 증가합니다. 만약 여러 클라이언트가 동시에 같은 데이터를 업데이트하려고 할 때, 최초의 성공한 트랜잭션만이 버전 번호를 업데이트하고, 나머지 트랜잭션들은 버전 불일치로 인해 실패하게 됩니다.

예상하신 바와 같이, OptimisticLockStockFacade 클래스에 @Transactional을 붙이면 해당 클래스의 메서드들이 하나의 트랜잭션으로 묶이게 됩니다. 이로 인해 만약 해당 메서드 내에서 버전 불일치로 인해 실패하고 재시도하는 로직이 있다면, 재시도할 때도 기존 트랜잭션 내에서 실행되므로 동일한 엔티티 매니저와 연결된 기존 버전의 데이터를 참조하게 됩니다. 따라서 업데이트에 실패한 이후에도 무한히 같은 버전의 데이터로 재시도하면서 무한 루프에 빠지는 것입니다.

이 문제에 대한 해결책으로는 재시도 로직을 갖는 메서드를 @Transactional의 적용 범위 밖으로 분리하는 방법이 있습니다. 다시 말해, 재시도를 담당하는 메서드는 별도의 트랜잭션을 시작하여 실패시마다 새로운 트랜잭션에서 재시도 할 수 있도록 구성해야 합니다. 이를 통해 실패한 경우 새 트랜잭션으로부터 최신 버전의 데이터를 가져와 재시도하게 되므로 무한 루프를 방지할 수 있습니다.

이와 유사한 내용을 다루는 기존 답변이 있습니다. 아래 링크를 참고하시면 이해하시는 데 도움이 될 것입니다.

기존 답변에서도 Isolation Level과 관련하여 낙관적 락의 동작 원리 및 무한 루프에 빠지는 현상에 대해 상세히 설명하고 있으며, 그 원인과 해결 방안에 대해 토론하는 내용을 살펴볼 수 있습니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

레디선 테스트코드에서 채널이름은 없어도 되는건가요?

0

43

2

낙관적 락을 사용할 떄 차이점

0

119

2

동시성 검증 코드에 관한 문의

0

94

2

단일연산

0

70

2

낙관적락vs. 레디스락

0

108

2

안녕하세요. 레디슨 질문있습니다..!!

0

67

2

@Lock(OPTIMISTIC)이 필요한 이유

0

90

2

get_lock 의 timeout이 3000초 이던데 너무 긴거 아닌가요?

0

131

2

DataSource Hikari 사용 이유

0

145

2

saveAndFlush 사용 이유 문의

0

112

3

비관적 락 VS 네임드 락

0

159

3

application.yaml 에 redis 정보

0

99

2

왜 클래스 이름에 Facade 가 붙나요?

0

183

2

@Transactional 으로 인한 동시성 문제 발생 원인이 궁금합니다.

0

219

2

@modifying 이용한 동시성 제어

0

168

2

DB락과 분산락

0

260

2

NamedLock 테스트 실패

0

186

2

테스트에서 트랜잭션 어노테이션 질문 있습니다.

0

172

2

optimistic Lock 재시도 질문입니다.

0

230

2

낙관적 락 테스트 실패

0

239

2

오류?

0

1626

4

LettureLockStockFacadeTest에서 오류가 발생합니다.

1

268

2

Pessimistic Lock 전체 테스트 오류 문의

0

359

3

비관적 락 vs 레디스(Lettuce)락 비교 관련 질문

0

460

2