흔히들 많이 사용하고 기본적으로 작동하는 것이 Propagation.REQUIRED 전파 레벨을 사용한다.
그 다음은 여러 이유로 REQUIRES_NEW 전파 레벨이 사용되는 편인데, 이 둘의 개념을 먼저 간단히 살펴보자.
Propagation.REQUIRED
트랜잭션이 존재하면 기존의 트랜잭션이 전파된다. 만약 존재하지 않는다면 트랜잭션을 새로 시작한다.
Propagtion.REQUIRES_NEW
매번 새로운 트랜잭션을 생성한다.
그렇다면 REQUIRES_NEW는 부모 트랜잭션에서 완전 독립적인 트랜잭션을 생성하는가 ?
꽤나 많은 곳에서 REQUIRES_NEW는 부모와는 아예 독립된 공간을 생성하는 것으로 표현되고 있고 나 역시 그렇게 알고 있었다.
독립된 공간은 부모 트랜잭션과 새롭게 생긴 자식 트랜잭션이 exception으로부터 완전 독립된 것으로 이해했다.
하지만 실제로는 그렇지 않았다.
결론부터 말하자면 새롭게 생긴 자식 트랜잭션에서 Exception이 발생하면 부모 트랜잭션까지 전파된다.
예제를 살펴보자
1. 부모 Tx -> 자식 New Tx Exception 발생
fun propagation() {
println("parent tx start !")
repository.save(FruitInfo(name = "banana"))
// throw exception in requires_new tx
propagationService.childRequiresNewTxIncludeException()
// 부모 tx -> 자식 tx (exception 발생) : 부모 + 자식 둘 다 롤백
}
2. 부모 Tx -> 자식 New Tx -> 부모 Tx Exception 발생
fun propagation() {
println("parent tx start !")
repository.save(FruitInfo(name = "banana"))
propagationService.childRequiresNewTx()
throw RuntimeException()
// 부모 tx -> 자식 tx -> 부모 tx (exception 발생) : 자식 tx는 커밋되고 부모만 롤백
}
그럼 어떤 경우에 REQUIRES_NEW 전파 레벨을 사용하는 것이 좋을까?
여러 경우가 있겠지만 몇가지만 뽑으면 다음과 같다.
- 부모 트랜잭션에서 Exception이 발생해도 커밋이 되어야 하는 경우
- 부모 트랜잭션에서 자식 트랜잭션을 try - catch 하고 싶은 경우 (일반 트랜잭션으로 하면 try - catch가 롤백 마킹때문에 의도대로 작동하지 않음)
'Programming > Java & JSP & Spring' 카테고리의 다른 글
[Spring] 외부 API 호출 서비스 테스트코드 작성하기 (WebClient & MockWebServer) (0) | 2022.03.13 |
---|---|
[Spring boot] Hikari CP 적용 & 커넥션 누수 이슈 (0) | 2022.02.01 |
나만의 코딩컨벤션 작성하기(Spring, Java, Naming, 구조, 코드 작성법 등) (2) | 2020.04.04 |
[Spring] Retry 재시도 로직 구현하기 With Kotlin (0) | 2020.02.29 |
JPA 변경감지(Dirty Checking)과 OSIV (0) | 2020.01.26 |