카테고리 없음

Spring boot 트랜잭션에 대한 간단한 정리

책다니엘 2025. 3. 27. 19:21

1. isolation — 트랜잭션 격리 수준

트랜잭션 간의 읽기/쓰기 충돌을 어떻게 막을지 설정합니다.

 
@Transactional(isolation = Isolation.REPEATABLE_READ
설명 방지되는 문제
READ_UNCOMMITTED 커밋 안 된 데이터도 읽기 허용 없음 (가장 낮은 수준)
READ_COMMITTED 커밋된 데이터만 읽음 (기본) Dirty Read 방지
REPEATABLE_READ 트랜잭션 동안 같은 행은 같은 값으로 보장 Non-repeatable Read 방지
SERIALIZABLE 가장 엄격한 수준, 전체 정렬된 트랜잭션처럼 동작 Phantom Read까지 방지

💡 기본값은 DBMS에 따라 다르지만 대부분 READ_COMMITTED


2. propagation — 트랜잭션 전파 방식

이미 진행 중인 트랜잭션이 있다면 이 메서드는 어떻게 실행되어야 할까?

 
@Transactional(propagation = Propagation.REQUIRED)
설명
REQUIRED 기존 트랜잭션이 있으면 참여, 없으면 새로 시작 (기본값)
REQUIRES_NEW 무조건 새 트랜잭션 시작 (기존 것은 일시 중단)
NESTED 부모 트랜잭션 안에 중첩 트랜잭션 시작 (rollback 분리 가능)
SUPPORTS 트랜잭션 있으면 참여, 없으면 그냥 실행
MANDATORY 반드시 트랜잭션 있어야 함, 없으면 예외
NEVER 트랜잭션 있으면 예외 발생
NOT_SUPPORTED 트랜잭션 없이 실행 (기존 트랜잭션 중단)

🧠 트랜잭션 분리/중첩이 필요한 경우 반드시 설정 고려


3. readOnly — 읽기 전용 최적화

 
@Transactional(readOnly = true)
  • 쓰기 연산이 없는 메서드에 설정하면 성능 최적화
  • JPA에서는 **더티 체킹(변경 감지)**이 비활성화되어 flush 생략 가능

⚠️ 주의:

  • readOnly = true인데 save() 등 쓰기 시도하면 예외는 나지 않지만 의도와 어긋납니다

4. rollbackFor — 트랜잭션 롤백 예외 지정

Spring은 기본적으로 RuntimeException과 Error만 롤백 대상입니다.
하지만 체크 예외(Exception)가 발생하면 롤백이 되지 않아요.

@Transactional(rollbackFor = IOException.class)
  • 이 설정을 통해 체크 예외로도 롤백이 가능하게 만듭니다

✅ 반대 설정도 있음: noRollbackFor


5. timeout — 트랜잭션 최대 실행 시간 (초 단위)

 
@Transactional(timeout = 10) // 10초 안에 끝나야 함
  • 트랜잭션이 설정한 시간 안에 끝나지 않으면 롤백 발생
  • DB 락 대기 방지, 무한 대기 방지용으로 사용

⚠️ JPA 사용 시에는 실제 DB에 따라 제대로 적용되지 않는 경우도 있음 → DB 설정 병행 필요


✨ 종합

@Transactional(
isolation = Isolation.REPEATABLE_READ, 
propagation = Propagation.REQUIRES_NEW, 
readOnly = false, 
rollbackFor = {SQLException.class}, 
timeout = 5 
) 
public void updateAccount() { 
// 5초 안에 끝나야 하고, 
// 별도 트랜잭션으로 실행되며,
// SQLException 발생 시 롤백됩니다.
}

✅ 요약표

속성 역할
isolation 트랜잭션 간 읽기 격리 수준 설정
propagation 트랜잭션 전파 방식 제어
readOnly 읽기 전용 최적화 (쓰기 방지)
rollbackFor 어떤 예외에서 롤백할지 지정
timeout 트랜잭션 최대 실행 시간 제한 (초 단위)