티스토리 뷰

Spring

[Spring] 트랜잭션 추상화

hyuuny 2025. 1. 12. 17:06

만약 서비스 계층이 JDBCRepository 구현체에 의존하고 있는 상황에서, 향후 JPA와 같은 다른 데이터 접근 기술로 변경하면 서비스 계층의 트랜잭션 관련 코드도 모두 변경해주어야 합니다.


JDBC 트랜잭션 의존

JDBC -> JPA로 변경


이 문제를 해결하기 위해서는 트랜잭션 기능을 추상화하면 됩니다. 단순하게 생각해보면 아래와 같이 인터페이스를 만들어서 사용하면 될 것 입니다.

public interface TxManager {
    begin();
    commit();
    rollback();
}

트랜잭션 추상화와 의존관계

서비스는 특정 트랜잭션 기술에 직접 의존하는 것이 아니라, TxManager라는 추상화된 인터페이스에 의존하고 있습니다. 이제 원하는 구현체를 DI를 통해서 주입받기만 하면 되는데, 예를 들어 JDBC 트랜잭션 기능이 필요하면 JdbcTxManager를 주입받고, JPA 트랜잭션 기능으로 변경해야 하면 JPATxManager를 주입받으면 됩니다.


만약 서비스에서 인터페이스가 아닌 구현체에 직접 의존하였다면, 아래와 같이 기능을 변경하면서 이에 의존하는 서비스 코드도 함께 변경해야 되어야 합니다.하지만 클라이언트인 서비스는 인터페이스에 의존하고 DI를 사용한 덕분에 OCP 원칙을 지킬 수 있게 되었습니다.

public class ReviewService {
    // private final JdbcTxManager jdbcTxManager;
    private final JpaTxManager jpaTxManager;
}

스프링의 트랜잭션 추상화

정말 편리하게도 스프링에서는 이미 트랜잭션을 추상화해두었습니다. 또한, 데이터 접근 기술에 따른 대부분의 트랜잭션 구현체도 만들어 두었기 때문에 개발자는 이를 가져다 사용하기만 하면 됩니다.




  • getTransaction(): 트랜잭션을 시작합니다.(기존에 이미 진행중인 트랜잭션이 존재하면, 해당 트랜잭션에 참여합니다.)
  • commit(): 트랜잭션을 커밋합니다.
  • rollback(): 트랜잭션을 롤백합니다.

스프링 트랜잭션 추상화의 핵심인 PlatformTransactionManager 인터페이스입니다. 스프링 5.3부터는 JDBC 트랜잭션을 관리할 때 DataSourceTransactionManager를 상속받아서 약간의 기능을 확장한 JdbcTransactionManager를 제공합니다. 둘의 기능 차이는 크지 않기 때문에 같은 것으로 이해하시면 됩니다.


트랜잭션 동기화

스프링에서 제공하는 트랜잭션 매니저는 트랜잭션 추상화리소스 동기화라는 크게 두 가지 역할을 합니다.


커넥션과 세션


트랜잭션 매니저와 트랜잭션 동기화 매니저


동작 방식을 간단하게 살펴보면 아래와 같습니다.

  1. 트랜잭션 매니저는 데이터소스를 통해 커넥션을 만들고 트랜잭션을 시작한다.
  2. 트랜잭션 매니저는 트랜잭션이 시작된 커넥션을 트랜잭션 동기화 매니저에 보관한다.
  3. Repository는 트랜잭션 동기화 매니저에 보관된 커넥션을 꺼내서 사용한다.
  4. 트랜잭션이 종료되면 트랜잭션 매니저는 트랜잭션 동기화 매니저에 보관된 커넥션을 통해 트랜잭션을 종료하고, 커넥션도 닫는다.

트랜잭션 매니저는 내부적으로 트랜잭션 동기화 매니저를 사용하고, 이것은 쓰레드 로컬(쓰레드 로컬을 사용하면 각각의 쓰레드마다 별도의 저장소가 부여되고, 해당 쓰레드만이 데이터에 접근할 수 있습니다.)을 사용해서 커넥션을 동기화합니다. 쓰레드 로컬을 사용하기 때문에 멀티쓰레드 상황에서 안전하게 커넥션을 동기화할 수 있습니다.

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함