스프링
스프링 - 트랜잭션 이해 (2)
개발자 포비
2024. 12. 13. 11:47
Spring 트랜잭션의 이해
1. 트랜잭션 동작 원리
- Spring의 트랜잭션은 프록시를 통해 작동
- @Transactional이 선언된 메서드 호출 시, 트랜잭션 프록시가 먼저 개입
[Client] -> [@Transactional Method]
|
v
[Transaction Proxy]
|
v
[Real Method]
2. 트랜잭션 동기화 매니저
- ThreadLocal을 사용하여 트랜잭션 정보 관리
- 각 스레드별로 독립적인 트랜잭션 관리
// TransactionSynchronizationManager private static final ThreadLocal<Map<Object, Object>> resources; private static final ThreadLocal<String> currentTransactionName;
3. 내부/외부 트랜잭션
[Transaction Flow]
[Outer Transaction] --> [Inner Transaction]
(신규 트랜잭션 O) (신규 트랜잭션 X)
1. 트랜잭션 시작 7. 트랜잭션 존재 확인
2. 커넥션 획득 8. 기존 트랜잭션 참여
3. autoCommit(false) 9. 로직 실행
4. 커넥션 보관
5. 로직 실행
[Transaction Synchronization Manager]
(ThreadLocal Storage에서 관리)
4. 트랜잭션 전파
- REQUIRED (기본값)
- 외부 트랜잭션 있으면: 참여
- 없으면: 새로 생성
- REQUIRES_NEW
- 항상 새로운 트랜잭션 생성
- 물리적으로 독립된 트랜잭션
[REQUIRED] [REQUIRES_NEW]
T1 시작 T1 시작
└─ T2 (T1에 참여) └─ T2 (새로운 트랜잭션)
(T2 완료 후 T1 재개)
5. 물리/논리 트랜잭션
- 물리 트랜잭션: 실제 DB 커밋/롤백 단위
- 논리 트랜잭션: 트랜잭션 매니저가 관리하는 단위
[REQUIRED 예시]
논리1 ─┐
논리2 ─┼─ 하나의 물리 트랜잭션
논리3 ─┘
[REQUIRES_NEW 예시]
논리1 = 물리1
논리2 = 물리2
논리3 = 물리3
6. 주의사항
- 같은 클래스 내부 호출: 트랜잭션 적용 안됨
- private 메서드: @Transactional 동작 안함
- RuntimeException: 기본적으로 롤백
- Checked Exception: 기본적으로 롤백 안함
7. 해결방법
// 1. 다른 클래스로 분리
@Service
class ServiceA {
private ServiceB serviceB;
@Transactional
public void methodA() {
serviceB.methodB(); // 트랜잭션 적용
}
}
// 2. self 주입
@Service
class Service {
@Autowired
private Service self;
@Transactional
public void methodA() {
self.methodB(); // 트랜잭션 적용
}
}