최근 리팩토링 작업을 진행하고 있다.
리팩토링 작업을 진행하던 도중 Transaction들이 Chain Transaction Manager로 묶여있는 걸 확인할 수 있었고 해당 Manager가
Deprecated가 된 상태로 있는 이슈가 있어 해당 부분을 개선하고자 했다.
개선 도중 이 내부는 어떻게 동작되고 있고 개선 대안은 어떤 게 있는지 의문점이 들었었고 해당 부분을 개선하는 도중 내부 동작을 기억하고자 글을 적게 되었다.
개선하면서 하나씩 더 채워보려고 한다.
위 트랜잭션 매니저는, Spring Data Commons에서 공식적으로 지원하는 라이브러리이다.
해당 기술의 내부 구조를 간단하게 살펴본다면 여러개의 나눠진 트랜잭션 매니저를 하나로 묶어 사용하는 방식이다.
묶인 트랜잭션은 순차적으로 트랜잭션을 실행하고 역순으로 Commit이 진행된다. 말로만 해서는 어떤 느낌인지 감이 안 온다. 한번 그림과 내부 구현체를 보면서 살펴보자
간단하게 다이어그램으로 흐름도를 파악해보았으니, 내부 구현체를 통해 어떻게 진행되는지 한번 파악해보고자 한다.
기본적으로 각 체이닝을 위해 선언된 PlatformTransactionManger 배열들이 파라미터로 요청이 들어왔을 때,
해당 매니저들과 매니저들의 리소스 동기화를 위해, SyncronizationManager을 함께 생성함수로 전달하고 있음을 확인할 수 있다.
해당 주 생성 함수에서는 Assert를 통해 Null safety 하게 관리하기 위해 검증하고 있음을 확인할 수 있다.
그렇다면 어떻게 역순으로 커밋 또는 롤백이 진행되고 있을까?
commit 내부를 보니, 각 선언된 Managers를 reverse를 통해 역순으로 실행하고 있음을 확인할 수 있다.
내부 동작원리는 다음과 같은 순서대로 진행됨을 확인할 수 있었다.
예외처리 시, 다음과 같은 구조로 실행되고 있음을 확인할 수 있다.
다음은 Rollback 메서드의 내부를 살펴보자
Rollback의 경우, MultiTransactionStatus를 롤백하고 각 트랜잭션 매니저에 롤백을 시도한다.
순서는 다음과 같다.
그 후, 각 if문을 통해 아래와 같은 수행을 진행합니다.
commit, rollback 두 개 다 reverse라는 메서드를 통해 역순으로 동작이 이뤄진다. 해당 메서드는 private 메서드로 선언되어 있음을 확인할 수 있었다.
그렇다면, 왜 reverse를 통해 역순으로 트랜잭션을 처리할까?
공통적인 이유는 다음과 같다.
그와 별개로 커밋과 롤백 시 역순으로 진행되는 이유는 각각 다음과 같다.
Spring Transaction 전파 원리를 생각해 보며 다시 생각해 보니 당연한 이야기임을 알 수 있었다.
현재 ChainedTransactionManager는 Deprecated 가 되어있는 상황이다. 이는 2.5 버전 이후부터는 사용되지 않음을 확인할 수 있었다.
해당 그림을 다시 한번 살펴보고 내부 소스를 다시한번 생각해 보자
각 트랜잭션들은 체이닝 되어 관리가 되고 있고, 보장 순서도 역순으로 보장이 이뤄지고 있다.
다음과 같은 요구사항을 두고 한번 더 생각해 보자
admin (Start) -> auth (Start) -> Logic -> auth (COMMIT) -> admin (ROLLBACK)
auth 이 COMMIT 된 이후에 admin 가 ROLLBACK이 된다면 auth은 이미 COMMIT이 되었기에 ROLLBACK 되지 않아 데이터에 문제가 발생
즉, 트랜잭션의 원자성에 어긋나는 결과가 발생할 수 있다.
그렇기에, 체이닝을 할 때는 순서가 중요하다.
해당 순서를 통해 알 수 있듯 Rollback은 나중에 선언된 트랜잭션에서 에러가 발생할 경우 Rollback 보장이 이뤄지기에 에러가 날 확률이 높은 트랜잭션을 후순위 Chain으로 묶어줘야 안전한 트랜잭션을 구성할 수 있다.
이에 대한 대안으로는 다음과 같은 방법을 생각해보았다.
해당 방법 하나씩 테스트를 진행해 보며 적합한 방법을 찾아보고 적용해 보며 자세하게 더 포스팅을 해보려고 한다.
https://taes-k.github.io/2020/06/09/chained-transaction-manager/
https://github.com/spring-projects/spring-data-commons/issues/2232
https://wannaqueen.gitbook.io/spring5/spring-boot/undefined-1/39.-jta-by-ys
더 간편하게 내부 코드를 보시기 위해서는 아래 링크를 참조하시면 됩니다.
Feature Flags? 누구냐 넌 (1) | 2024.02.19 |
---|---|
실시간 코인시세 어디까지 알아봤니? part 1 (1) | 2023.08.14 |
빗썸 API를 활용한 매수 / 매도 데이터 적재 (1) | 2023.06.11 |
[Spring Boot + Chat GPT] Open AI API 적용기 (1) | 2023.04.16 |
분산락과 네임드락 그리고... 동시성 (1) | 2023.02.02 |