본문 바로가기
Spring Study/DataBase

[DataBase] 스프링 트랜잭션 이해

by 정재인 2023. 10. 6.

트랜잭션(Transaction) 이란?

· 데이터베이스의 상태를 변화시키기 해서 수행하는 작업의 단위를 뜻한다.

· 스프링은 PlatformTransactionManager라는 인터페이스를 통해 트랜잭션을 추상화한다.

 

PlatformTransactionManager 인터페이스

package org.springframework.transaction;
    
public interface PlatformTransactionManager extends TransactionManager {
      
    TransactionStatus getTransaction(@Nullable TransactionDefinition definition) throws TransactionException;
        void commit(TransactionStatus status) throws TransactionException;
        void rollback(TransactionStatus status) throws TransactionException;
}

 

· 스프링은 트랜잭션을 추상화해 제공할 뿐만 아니라, 실무에서 주로 사용하는 데이터 접근 기술에 대한 트랜잭션 매니저의 구현체도 제공한다. 개발자는 필요한 구현체를 스프링 빈으로 등록하고 주입 받아 사용하면 된다.

· 스프링 부트는 어떤 데이터 접근 기술을 사용하는지를 자동으로 인식해서 적절한 트랜잭션 매니저를 선택해 스프링 빈으로 등록해준다.

 

스프링 트랜잭션 사용 방식

PlatformTransactionManager를 사용하는 2가지 방법

· 선언적 트랜잭션 관리
· 프로그래밍 방식 트랜잭션 관리

 

☞ 선언적 트랜잭션 관리 (Declarative Transaction Management)

· @Transactional 애노테이션 하나만 선언해 매우 편리하게 트랜잭션을 적용한다.

· 선언적 트랜잭션 관리는 과거 XML에 설정하기도 했다.

· 이름 그대로 어딘가에 선언하기만 하면 트랜잭션이 적용되는 방식이다.

· 실무에서는 대부분 선언적 트랜잭션 관리를 사용한다.

 

프로그래밍 방식 트랜잭션 관리 (Programmatic Transaction Management)

· 트랜잭션 매니저 또는 트랜잭션 템플릿 등을 사용해 트랜잭션 관련 코드를 직접 작성한다.

 

 

선언적 트랜잭션과 AOP

@Transactional을 통한 선언적 트랜잭션 관리 방식을 사용하게 되면 기본적으로 프록시 방식의 AOP가 적용된다.

 

프록시 도입 전

//트랜잭션 시작
TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());

try {
    //비즈니스 로직
    bizLogic(fromId, toId, money); 
    transactionManager.commit(status);//성공시 커밋
    } catch (Exception e) { 
        transactionManager.rollback(status);//실패시 롤백
        throw new IllegalStateException(e);
}

 

프록시 도입 후

public class TransactionProxy {
    private MemberService target;
    
    public void logic() {
    //트랜잭션 시작
    TransactionStatus status = transactionManager.getTransaction(..);
        try {
            //실제 대상 호출 target.logic();
            transactionManager.commit(status);//성공시 커밋 
            }catch (Exception e) {
                transactionManager.rollback(status);//실패시 롤백
                throw new IllegalStateException(e);
          }
    }
}
public class Service {

    public void logic() {
    //트랜잭션 관련 코드 제거, 순수 비즈니스 로직만 남음
        bizLogic(fromId, toId, money);
    }
}
· 프록시 도입 전: 서비스에 비즈니스 로직과 트랜잭션 처리 로직이 함께 섞여있다.
· 프록시 도입 후: 트랜잭션 프록시가 트랜잭션 처리 로직을 모두 가져가고, 서비스 계층에는 순수 비즈니스 로직만 남길 수 있다.

 

프록시 도입 후 전체 과정

· 스프링 부트를 사용하면 트랜잭션 AOP를 처리하기 위해 필요한 스프링 빈들도 자동으로 등록해준다.

· 스프링은 트랜잭션 처리가 필요한 곳에 @Transactional 애노테이션만 붙여주면, 트랜잭션 AOP는 이 애노테이션을 인식해 트랜잭션을 처리하는 프록시를 적용해준다.

 

 


 

트랜잭션 적용 위치

· 스프링에서 우선순위는 항상 더 구체적이고 자세한 것이 높은 우선순위를 가진다.

· @Transactional == @Transactional(readOnly = false)

· 스프링 @Transactional은 두 가지 규칙이 있다.

1. 우선순위 규칙
2. 클래스에 적용하면 메서드는 자동 적용

 

예외와 트랜잭션 Commit, Rollback

· 예외 발생시 스프링 트랜잭션 AOP는 예외의 종류에 따라 트랜잭션을 커밋하거나 롤백한다.

· 언체크 예외RuntimeException, Error와 그 하위 예외가 발생하면 트랜잭션을 롤백한다.

· 체크 예외Exception과 그 하위 예외가 발생하면 트랜잭션을 커밋한다.

· 정상 응답하면 트랜잭션을 커밋한다.

· 체크 예외: 비즈니스 의미가 있을 때 사용 (commit)
· 언체크 예외: 복구 불가능한 예외 (rollback)

 

'Spring Study > DataBase' 카테고리의 다른 글

[DataBase] JPA / Spring Data JPA  (0) 2023.10.03
[DataBase] 데이터 접근 기술 - 테스트  (0) 2023.09.25
[DataBase] 데이터 접근 기술  (0) 2023.09.22
[DataBase] 예외 처리  (0) 2023.09.21
[DataBase] 자바 예외 (Exception)  (0) 2023.09.20

댓글