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

fpg123님의 프로필 이미지
fpg123

작성한 질문수

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

NamedLock 에서  @Transactional 사용에 관한 질문

작성

·

141

0

NamedLock을 사용한 예제실습 중 질문입니다

  • NamedLockStockFacade의 decrease 메소드에 @Transactional 을 걸고 StockService의  decrease 메소드에는 @Transactional 을 걸지 않아도 잘 작동해야하는거 같은데, 데드락에 걸리는거 같습니다. 그 이유가 궁금합니다

  • 제 생각에는 NamedLockStockFacade의decrease 메소드에 @Transactional 을 걸면,
    lockRepository.getLock(id.toString()), stockService.decrease(id, quantity), lockRepository.releaseLock(id.toString()) 이 3 메소드가 모두 한 트랜잭션 안에서 처리되므로 lock을 걸고 lock을 해제하는 그 사이에 재고를 감소하므로 아무 문제가 없어보여서 질문드립니다.

답변 2

0

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

fpg123 님 안녕하세요.
글로만 봐서는 어떤 상황인지 정확하게 이해가 되지 않습니다.
혹시 문제가 되는 소스를 깃헙에 올려주신 후 주소를 공유해주실 수 있으실까요 ?

0

안녕하세요, 인프런 AI 인턴입니다.

NamedLock을 사용하는 상황에서 @Transactional을 건 메소드가 데드락에 걸리는 이슈가 발생하는 경우, 트랜잭션 범위와 각 메소드에서 이루어지는 데이터베이스 락의 종류와 순서를 확인해야 합니다. 여기에서는 몇 가지 가능성을 생각해 볼 수 있습니다.

NamedLockStockFacade의 decrease 메소드에 @Transactional 어노테이션이 걸려 있으면 해당 메소드 안에서 실행되는 모든 데이터베이스 관련 작업들은 하나의 트랜잭션으로 묶이게 됩니다. 이 때 lock을 획득하고, 재고를 감소한 다음 lock을 해제하는 과정은 해당 트랜잭션 범위 안에서 이루어집니다.

그럼에도 불구하고, 데드락이 발생한다면, 아래와 같은 이유를 고려해 볼 수 있습니다:

  1. 동시에 여러 트랜잭션이 같은 자원에 대해 lock을 획득하려고 시도할 때 발생할 수 있습니다. 이 경우 서로 다른 트랜잭션들이 서로를 기다리는 상황이 발생하여 데드락이 발생할 수 있습니다.
  2. 다른 메소드나 트랜잭션이 lock의 해제 없이 같은 자원에 접근하려고 한다면, 이미 lock이 걸려있기 때문에 데드락이 발생할 수 있습니다.
  3. 기본적으로 @Transactional이 붙은 메소드 내에서 발생하는 쿼리들은 하나의 트랜잭션으로 묶이며, 장시간 실행되는 쿼리나 업데이트로 인한 락 경쟁이 늘어날 경우 데드락 위험성이 증가합니다.

해결방법에는 여러가지가 있을 수 있는데, 트랜잭션의 범위를 줄이거나, 락을 획득하는 순서를 일관되게 하여 데드락의 가능성을 줄이는 전략 등이 있을 수 있습니다. 문제가 되는 상황에 대한 더 구체적인 분석이 수행되어야 할 것입니다.

데드락 문제 해결에 있어서는 일반적으로 트랜잭션의 범위를 최소화하고, 필요한 경우 적절한 격리수준(isolation level) 설정, 락 획득의 순서와 시도 시간 제한(timeout) 설정 등 다양한 접근 방식을 취할 수 있습니다. 이러한 전략이 올바르게 적용되었는지 다시 한번 검토해 보시는 것이 좋을 것 같습니다.

fpg123님의 프로필 이미지
fpg123

작성한 질문수

질문하기