![[Spring] 트랜잭션 매니저 구현체를 bean으로 등록해야할까?](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fly9cL%2FbtsqvjTIVfh%2FVJY5EsmuDMdHypYsJmVRq0%2Fimg.png)
트랜잭션의 경우 서비스 계층의 비즈니스 로직에서 수행한다. 서비스 계층의 경우 트랜잭션 매니저(PlatformTransactionManager)를 사용하고 데이터 접근 계층에서는 트랜잭션 동기화 매니저(DataSourceUtils)를 사용한다. 데이터 접근 계층은 트랜잭션 동기화 매니저가 관리하는 커넥션을 꺼내어 사용하는데, 트랜잭션 동기화 매니저에 커넥션을 저장하는 것은 서비스 계층의 트랜잭션 매니저가 수행한다.
서비스 계층
서비스 계층에서 트랜션을 실행하여 커넥션을 만들고 이 커넥션을 트랜잭션 동기화 매니저에 저장시킨다. 스프링에서 사용하는 트랜잭션 매니저는 PlatformTransactionManager이다. 트랜잭션 매니저의 구현체로는 DataSourceTransactionManager, JpaTransactionManager 등이 있다.
의문점
일단 아래 코드를 보자.
서비스 계층
Bean Factory에 bean으로 등록된 DataSourceTransactionManager를 트랜잭션 매니저(PlatformTransactionManager)에 의존성 주입을 한다.
// 서비스 계층
@Service
public class MemberServiceV3 implements MemberService {
private MemberRepository memberRepository;
private PlatformTransactionManager txManager;
@Autowired
public MemberServiceV3(MemberRepository memberRepository, PlatformTransactionManager txManager) {
this.memberRepository = memberRepository;
this.txManager = txManager;
}
// 생략..
}
Bean Factory
서비스 계층의 트랜잭션 매니저(PlatformTransactionManager)에 의존성 주입을 할 DataSourceTransactionManager 구현체를 Bean으로 등록한다.
// Bean Factory
@SpringBootApplication
public class JdbcApplication {
public static void main(String[] args) {
SpringApplication.run(JdbcApplication.class, args);
}
@Bean
public DataSource dataSource() {
HikariDataSource dataSource = new HikariDataSource();
dataSource.setJdbcUrl(URL);
dataSource.setUsername(USERNAME);
dataSource.setPassword(PASSWORD);
return dataSource;
}
@Bean
public PlatformTransactionManager dataSourceTransactionManager() {
return new DataSourceTransactionManager(dataSource());
}
}
일단 위의 코드에서는 문제가 없다. 그렇다면 Bean Factory에 bean으로 등록된 아래 코드를 주석처리하면 어떻게 될까?
나는 오류가 발생할 것이라고 생각했다. 그 근거로는 트랜잭션 매니저 구현체를 bean으로 등록하지 않았기 때문에 서비스 계층에서 의존성 주입이 정상적으로 이루어지지 않기 때문에 트랜잭션을 시작할 수 없다고 생각했다.
//Bean Factory
@Bean
public PlatformTransactionManager dataSourceTransactionManager() {
return new DataSourceTransactionManager(dataSource());
}
그러나 위의 코드를 주석처리 하더라도 정상적으로 트랜잭션이 수행된다. 그 이유로는 스프링 부트에서는 트랜잭션 매니저를 bean으로 자동으로 등록해 주기 때문이다. 어떤 트랜잭션 매니저를 주입할 지에 대해서는 스프링 부트에 설치된 라이브러리를 하나하나 확인하면서 알아서 판단해 준다.
참고로 아래 코드는 DataSource를 bean으로 자동 등록해준다.
// application.properties
spring.datasource.url=jdbc:h2:tcp://localhost/~/test
spring.datasource.username=sa
spring.datasource.password=
결론
스프링부트에서 트랜잭션 매니저 구현체를 bean으로 자동으로 등록하기 때문에 별도로 bean 등록할 필요가 없다.