개발놀이터

트랜잭션과 @Transactional 본문

Spring/Spring

트랜잭션과 @Transactional

마늘냄새폴폴 2022. 6. 21. 04:00

*트랜잭션

트랜잭션은 더 이상 쪼갤 수 없는 작업의 최소 단위를 의미한다. 즉 여러 작업을 진행하다가 문제가 생겼을 경우 롤백하기 위해 트랜잭션을 다누이로서 사용할 수 있다. 트랜잭션에는 commit, rollback 두 가지 경우가 존재한다. 모두 성공하여 commit되거나 하나라도 실패하면 rollback되는 것이다. 

 

Spring에서 제공하는 Transaction 기능

1. 트랜잭션 동기화

2. 트랜잭션 추상화

3. 트랜잭션 분리

 

1. 트랜잭션 동기화

개발자들이 JDBC의 모든 커넥션을 하나의 트랜잭션으로 관리하기 위한 작업을 직접 수행한다면 매우 번거로울 것이다. Spring에서는 이러한 문제를 해결하고자 트랜잭션 동기화 기술을 지원한다. 즉, 트랜잭션을 시작하기 위한 자원을 특별한 저장소에 보관해두고 꺼내쓸 수 있도록 한다.

 

하지만 이 기술은 JDBC에 종속적이기 때문에 이를 해결하기 위해 트랜잭션 추상화가 등장했다.

2. 트랜잭션 추상화

애플리케이션에서 사용할 수 있는 기술마다 종속적인 코드를 이용하지 않고도 일관되게 트랜잭션을 처리할 수 있도록 트랜잭션 추상화를 지원한다. 

이미지 출처: https://mangkyu.tistory.com/154

Spring이 제공하는 트랜잭션 경계 설정을 위한 추상 인터페이스는 PlatformTransactionManager이다. 이를 통해 사용하는 기술과 무관하게 트랜잭션을 공유 / 커밋 / 롤백할 수 있게 되었다.

 

하지만 비즈니스 코드와 트랜잭션 코드가 결합되는 것은 피하지 못했다. 

 

public void updateMember(Member member) {
    TransactionStatus status = this.transactionManager.getTransaction(new DefaultTransactionDefinition());
    
    try {
        if (validateMember(member)) {
            memberRepository.save(member);
        }
        this.transactionManager.commit(status);
    } catch (Exception e) {
        this.transactionManager.rollback(status);
        throw e;
    }
}

위 코드처럼 비즈니스 코드와 트랜잭션 코드가 결합되어 메서드 내에서 2가지 책임을 갖고 있게 되었다. 따라서 Spring에서는 트랜잭션 부분을 핵심 비즈니스 로직과 분리하였다. 

 

3. 트랜잭션 분리

트랜잭션과 핵심 비즈니스 로직을 분리하기 위해 선언적 트랜잭션 @Transactional을 지원하게 되었다. @Transactional은 스프링 AOP에 의해 만들어진 어노테이션이고 스프링이 프록시패턴을 이용해 만든 어노테이션이다. 

 

프록시 패턴이란?

https://coding-review.tistory.com/94

 

그래서 만들어진 코드가 바로 아래의 코드이다.

@Transactional
public void updateMember(Member member) {
    if (validateMember(member)) {
        memberRepository.save(member);
    }
}

이렇게 트랜잭션과 비즈니스 코드를 분리하는 작업까지 끝났다.