본문 바로가기
SpringBoot/데이터베이스 연동

트랜잭션 처리

by DEVLIB 2025. 4. 15.
728x90

트랜잭션(Transaction)이란?

정의

트랜잭션이란 DB 작업을 하나의 논리적인 단위로 묶는 것입니다.
이 작업은 **모두 성공하거나, 전부 실패(롤백)**해야 합니다.


특징 (ACID 원칙)

속성
설명
Atomicity (원자성) 모두 성공 또는 모두 실패
Consistency (일관성) 데이터 무결성 유지
Isolation (격리성) 동시성 충돌 방지
Durability (지속성) 커밋된 데이터는 영구 저장

스프링에서 트랜잭션 처리 방법

스프링에서는 @Transactional 애너테이션을 이용하여 매우 쉽게 트랜잭션을 처리할 수 있습니다.


기본 사용 방법

서비스 클래스에 적용

@Service
public class MemberService {

    private final MemberRepository memberRepository;

    public MemberService(MemberRepository memberRepository) {
        this.memberRepository = memberRepository;
    }

    @Transactional
    public void register(String name, String email) {
        Member m = new Member(name, email);
        memberRepository.save(m);

        // 예외 발생 시 트랜잭션 전부 롤백됨
        if (email.contains("error")) {
            throw new RuntimeException("이메일 오류 발생!");
        }
    }
}

@Transactional은 해당 메서드가 예외 발생 시 자동으로 롤백되도록 만듭니다.


주요 옵션들

옵션 설명 예시
readOnly = true 읽기 전용 트랜잭션 (성능 ↑) 조회 전용 서비스에 사용
rollbackFor = 예외.class 특정 예외 발생 시 롤백 @Transactional(rollbackFor = CustomException.class)
propagation 트랜잭션 전파 방식 지정 REQUIRED, REQUIRES_NEW, NESTED 등
timeout 제한 시간 초과 시 롤백 @Transactional(timeout = 5)

readOnly 예시

@Transactional(readOnly = true)
public List<Member> getAllMembers() {
    return memberRepository.findAll();
}

읽기 전용으로 선언하면 Hibernate는 더 이상 변경감지를 하지 않아 성능이 향상됩니다.


주의할 점

  1. @Transactional은 기본적으로 런타임 예외(RuntimeException)만 롤백합니다.
    • 체크 예외(Exception)는 롤백하지 않음
    • 필요 시 rollbackFor 명시해야 함
  2. 프록시 기반 동작이므로 같은 클래스 내부에서 호출하면 트랜잭션이 적용되지 않을 수 있음
  3. 트랜잭션은 보통 Service 계층에서 선언하는 것이 권장됨
    • Controller에서는 선언하지 않는 것이 일반적

테스트 예시

@SpringBootTest
public class MemberServiceTest {

    @Autowired
    MemberService memberService;

    @Autowired
    MemberRepository memberRepository;

    @Test
    void 트랜잭션_롤백_테스트() {
        try {
            memberService.register("홍길동", "error@email.com");
        } catch (Exception e) {
            // 롤백 됐는지 확인
            assertEquals(0, memberRepository.count());
        }
    }
}

마무리 요약

항목 설명
애너테이션 @Transactional
선언 위치 주로 Service 클래스
롤백 대상 기본: RuntimeException, 커스텀 지정 가능
성능 옵션 readOnly = true
실무 팁 비즈니스 로직 단위로 묶어서 선언할 것
LIST