작성
·
18
0
try {
getLock("쿠폰발급");
issueCoupon(); <- @Transactional(propagation = Propagation.REQUIERS_NEW)
} finally {
releaseLock("쿠폰발급");
}
의 형태로 되어있다면,
issueCoupon(); 메소드를 호출 할 때, Propagation.REQUIERS_NEW)
로 새로운 transaction 생성으로 인해 DB Connection을 확보하려 했지만 쿠폰 발급 요청이 몰려 DB namedLock 대기가 기존 connectionPool을 모두 차지하고 있어 timeout이 발생했다면, releaseLock에 기존 대기상태로 변환 트랜잭션이 실행되지 못 할 가능성이 존재할까요?
connectionTimeout 시간은 짧지만, namedLock 획득을 위한 대기 시간이 10분으로 되어있다고 가정하게 된다면 deadLock이 어디서 발생할 지 궁금합니다.
제가 생각한 건
issueCoupon(); 을 호출하면서 connecionPool 부족으로 인한, 기존의 getLock() 에 사용된 connectionPool이 대기 상태가 되면서 반환되고, 쿠폰 발급이 진행되고 이후 releaseLock()을 호출해야 하지만 connectionPool을 재확보하지 못 하고 Lock을 해제하지 못해 Lock 점유 시간동안
DeadLock 발생
issucoupon(); 에서 connectionPool을 확보하지 못해 timeoutException이 발생했지만
rollbackFor = Exception.class 로 인해 rollback을 위한 connectionPool()을 확보하기 위한 대기로 인한 DeadLock 발생
아직 기초 지식이 부족해 어떻게 deadLock이 발생하는지 모르겠습니다. 도움 부탁드립니다.
답변 1
0
안녕하세요, 인프런 AI 인턴입니다. 태훈님.
질문하신 내용은 HikariCP의 connection pool과 관련된 deadlock 상황에 대한 것입니다. 상황을 분석해 보면, 다음과 같은 이유로 deadlock이 발생할 가능성이 있습니다:
Connection Pool 고갈로 인한 문제: @Transactional(propagation = Propagation.REQUIRES_NEW)
는 항상 새로운 트랜잭션을 시작합니다. 이 경우 새로운 DB Connection을 확보해야 하며, 이미 모든 connection이 getLock("쿠폰발급")
등의 작업으로 대기 중이라면, 필요한 connection을 확보할 수 없어 timeout이 발생할 수 있습니다. 이때 releaseLock("쿠폰발급")
또한 connection을 필요로 하지만, connection을 확보하지 못하면서 교착상태에 빠질 수 있습니다.
트랜잭션 롤백으로 인한 문제: issueCoupon()
에서 timeoutException이 발생하고, Spring의 트랜잭션 관리자가 롤백을 시도하는 경우, 이 롤백 과정에서도 connectionPool에 있는 connection이 필요합니다. 하지만 connection이 여전히 부족하다면, 롤백을 위한 connection 확보가 지연되면서 deadlock이 발생할 수 있습니다.
해결책으로는 다음과 같은 방법을 고려해 볼 수 있습니다:
getLock
과 같은 메소드에서 사용이 끝난 connection을 명시적으로 반환하여, 다른 작업에서 사용 가능하도록 합니다.이러한 접근은 상황에 맞는 적절한 방법으로 문제를 해결할 수 있는 가능성을 제공합니다. 도움이 되었길 바랍니다.
추가적으로 관련된 내용을 더 확인하시려면, 다음 URL에서 참고 자료를 확인해 보세요: