1️⃣ 트랜잭션이 필요한 이유
모든 작업은 안전하게 끝나야 한다. 그렇지 않으면 무효다.
은행 송금처럼 "모두 성공" 또는 "모두 실패" 해야 하는 작업들을 처리할 때, 중간에 하나라도 실패하면 데이터가 엉킬 수 있습니다. 이런 상황을 막기 위해 도입된 것이 바로 트랜잭션입니다.
- 예: A → B 계좌 송금
- A 계좌에서 돈 빼기
- B 계좌에 돈 넣기
→ 둘 중 하나라도 실패하면 전부 되돌려야 함.
2️⃣ 트랜잭션의 4가지 성질 (ACID)
- Atomicity (원자성)
- 모두 실행되거나, 아무것도 실행되지 않아야 한다.
- Consistency (일관성)
- 트랜잭션 전과 후, 데이터는 일관된 상태를 유지해야 한다.
- Isolation (격리성)
- 동시에 실행되는 트랜잭션끼리는 서로 간섭하지 않아야 한다.
- Durability (지속성)
- 커밋된 트랜잭션 결과는 영구적으로 보장되어야 한다.
3️⃣ Spring에서의 트랜잭션 예시
@Transactional
public void transferMoney(Long fromId, Long toId, int amount) {
Account from = accountRepository.findById(fromId).orElseThrow();
Account to = accountRepository.findById(toId).orElseThrow();
from.decrease(amount);
to.increase(amount);
// 여기서 예외 발생 시 전체 rollback
}
- @Transactional 덕분에 예외가 발생하면 자동으로 rollback 됩니다.
- DB는 JPA or MyBatis 관계 없이 트랜잭션 단위로 동작합니다.
4️⃣ 전파(Propagation) 개념 정리
트랜잭션 안에서 또 다른 트랜잭션이 호출되면 어떻게 될까?
| 전파 속성 | 설명 |
| REQUIRED | 현재 트랜잭션이 있으면 참여, 없으면 새로 생성 |
| REQUIRES_NEW | 무조건 새 트랜잭션 생성 |
| NESTED | 중첩 트랜잭션 지원 (SavePoint 사용) |
실무에서는 REQUIRED, REQUIRES_NEW를 가장 많이 사용
5️⃣ 주의할 점
- 예외 처리 시 rollback 안 되는 경우
- 기본적으로 RuntimeException만 rollback 됨
- checked exception은 rollback 안 됨 → rollbackFor 사용 필요
@Transactional(rollbackFor = Exception.class)
- 프록시 기반 AOP → 내부 호출 시 트랜잭션 적용 안 됨
- this.method() 형태는 트랜잭션 적용 안됨 → @Transactional은 외부에서 호출되어야 적용됨
'SPRING' 카테고리의 다른 글
| [SPRING] JPA Proxy (3) | 2025.04.21 |
|---|---|
| [SPRING] 조인(JOINED) 전략 (2) | 2025.04.19 |
| [SPRING] 인터셉터 AOP (1) | 2025.04.15 |
| [SPRING] 뉴스피드 인덱스 실전 테스트 (0) | 2025.04.13 |
| [SPRING] 뉴스피드 과제 인덱스 성능 실험 (1) | 2025.04.13 |