devlog/TIL

Transactional + DDD

bandal-gom 2022. 9. 30. 22:25
2019년 12월 16일에 notion에 작성한 글을 옮겨 왔다.

@Transactional + DDD

fun requestRefund(request: RefundRequest): RefundResponse {
    val paymentInfo = 결제클라이언트.get결제정보(request.orderNo)
    return refund(refundDomainService.register(request, paymentInfo))
}

보통 외부의 호출이 일어날떄 transaction을 분리하는 경우는 다음과 같다.

  • transaction이 이미 열렸고, 외부 호출을 하는 경우 timeout 같은 에러 발생 시, 지연된 시간만큼 transaction을 물고 있기 때문에 좋지 않다. → db lock 발생 가능 (그런데 db lock은 정확히 언제 발생하는가? 🤔)

DB transaction의 시작은 refundDomainService.register 를 호출하였을때 시작이 된다. (정확하게 언제 시작되는지에 대해서 잘 모르겠다.)

register() 호출 이전에 transaction을 사용하고 있는 명령이 없기 떄문에, 해당 @Transactional 은 Application layer에 있는 것이 맞다.

이 이유 이외에도 Application layer에 두는 이유는 다음과 같다

  • DomainService layer에 있는 경우, 해당 function을 다른 곳에서 호출 하였을 떄 원하는 동작이 일어나지 않을 수도 있다. (ex. for loop으로 여러 컬렉션을 register 하게 되는 경우)
  • 위에 언급한 것과 같이 register() 이전에 transaction을 여는 다른 명령어가 있는 경우.

해당 domain function을 호출하는 곳에서 (Application layer) Transaction을 관리하는 것이 좀 더 용이하다.

Transaction이 이미 시작되었고 →외부 호출 (feign client) → register 로 만약에 코드가 짜여졌다면, transaction을 분리해서 가져가는 설계가 훨씬 맞다.

반응형