Spring 트랜잭션

김현찬·2025년 6월 23일

트랜잭션이란?

트랜잭션(Transaction)은 데이터베이스에서 하나의 논리적 작업 단위를 의미합니다. 여러 SQL 명령을 하나의 단위로 묶어 모두 성공하거나 모두 실패해야만 데이터 정합성을 유지할 수 있습니다.

예시

  • A → B 계좌 이체 작업
    • A의 잔액 차감
    • B의 잔액 증가
      → 하나라도 실패하면 전체 롤백되어야 함.

트랜잭션의 4가지 특성 (ACID)

속성설명
Atomicity (원자성)모든 작업이 전부 성공하거나 전부 실패해야 함
Consistency (일관성)트랜잭션 전후의 데이터가 항상 일관성 유지
Isolation (격리성)동시에 실행되는 트랜잭션 간 간섭 방지
Durability (지속성)커밋된 트랜잭션은 시스템 오류 발생해도 유지됨

예시

  • Atomicity
    • 주문 처리 중 결제는 되었는데 재고 차감 실패 → 전체 롤백
  • Consistency
    • 외래키, 제약조건, 형식 등이 트랜잭션 후에도 여전히 만족되어야 함
  • Isolation
    • 두 사용자가 동시에 같은 좌석을 예매하려고 할 때 충돌 방지
  • Durability
    • 결제 완료 후 서버가 다운되어도 결제 내역은 보존되어야 함

트랜잭션 제어 명령어

명령어설명
BEGIN트랜잭션 시작
COMMIT성공적으로 종료, 변경사항 반영
ROLLBACK오류 발생 시 변경사항 취소
SAVEPOINT중간 저장점 설정
RELEASE SAVEPOINT저장점 해제

예시

BEGIN;
UPDATE accounts SET balance = balance - 10000 WHERE id = 1;
UPDATE accounts SET balance = balance + 10000 WHERE id = 2;
COMMIT;
  • 중간에 오류 발생 시 ROLLBACK으로 두 작업 모두 취소 가능

Isolation Level (격리 수준)

트랜잭션 간 간섭을 얼마나 허용할 것인지 설정하는 기준입니다.

수준허용 정도발생할 수 있는 문제
READ UNCOMMITTED커밋 안 된 데이터 읽음Dirty Read
READ COMMITTED커밋된 데이터만 읽음Non-repeatable Read
REPEATABLE READ읽은 데이터 고정Phantom Read
SERIALIZABLE완벽한 격리, 가장 안전성능 저하 가능

예시

  • Dirty Read
    T1이 수정했지만 아직 COMMIT 안 한 데이터를 T2가 읽음 → 이후 ROLLBACK되면 데이터 모순
  • Non-repeatable Read
    T1이 조회한 데이터를 T2가 수정 → T1이 다시 조회 시 값 달라짐
  • Phantom Read
    T1이 조건으로 조회한 후, T2가 새 데이터를 INSERT → T1이 같은 조건으로 다시 조회하면 새로운 행이 생김
  • Serializable
    여러 트랜잭션이 직렬적으로 실행됨 → 모든 위 현상 방지 가능

Spring에서의 트랜잭션 관리

Spring에서는 @Transactional 어노테이션으로 트랜잭션을 선언적(명시적 코드 없이)으로 설정할 수 있습니다.

@Transactional
public void transfer(Long fromId, Long toId, int amount) {
    accountRepository.withdraw(fromId, amount);
    accountRepository.deposit(toId, amount);
}

예시 설명

  • 위 메서드 내에서 오류 발생 시 withdraw()도 자동으로 롤백
  • 예외가 발생하지 않으면 COMMIT 처리됨

예외와 롤백 조건

  • 기본적으로 RuntimeException 발생 시 자동으로 롤백됨
  • CheckedException은 기본적으로 롤백되지 않음 → 명시적으로 설정 가능
@Transactional(rollbackFor = SQLException.class)
public void doSomething() throws SQLException {
    // 예외 발생 시 롤백됨
}

트랜잭션과 테스트

  • 테스트 클래스나 메서드에 @Transactional을 붙이면 테스트 종료 시 자동으로 롤백되어 DB 상태가 유지됨
@SpringBootTest
@Transactional
public class UserServiceTest {
    // 테스트 DB 변경 후 자동 롤백됨
}

트랜잭션은 단순한 DB 조작이 아닌, 데이터 무결성과 동시성 문제를 방지하기 위한 핵심 개념입니다. 제대로 이해하고 설계에 반영하는 것이 안정적인 서비스 운영의 출발점입니다.

0개의 댓글