커넥션 풀 : 커넥션을 미리 생성해두고 사용. 커넥션 조회 -> 획득 -> 사용 -> 반환
트랜잭션 매니저 : 트랜잭션 관리해주는 애. 스프링 트랜잭션 추상화. 트랜잭션을 시작하려면 커넥션이 필요하다. 트랜잭션 매니저는 데이터소스를 통해 커넥션을 만들고 트랜잭션을 시작한다.
업무를 하다가 서비스단의 특정 메서드에서 @Transactional
애노테이션을 해줬음에도 불구하고 메서드 로직에 커넥션을 새로 받아와서 트랜잭션을 설정해주고 직접 커밋, 롤백을 하는 코드가 있었다.
그리고 이 부분을 똑같이 선언적 방식으로 트랜잭션을 관리하도록 변경해주어야했다.
@Transactional
만 되어있을 때는 기본 디폴트 데이터소스 설정을 따라간다.
기본 DB
<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<property name="poolName" value="A"/>
<property name="minimumIdle" value="1"/>
<property name="maximumPoolSize" value="100"/>
<property name="autoCommit" value="false"/>
</bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="transactionTemplate"
class="org.springframework.transaction.support.TransactionTemplate">
<property name="transactionManager" ref="transactionManager" />
</bean>
bean id="dataSource"의 접속정보가 나열되어있고,
bean id="transactionManager"가 "dataSource"에 해당하는 DB의 커넥션을 관리하겠다고 명시한 것이며 이 때 트랜잭션 이름은 "transactionManager" 이다.
또다른 DB
<bean id="SUBDataSource" class="com.zaxxer.hikari.HikariDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.SUB.driverClassName}"/>
<property name="jdbcUrl" value="${jdbc.SUB.url}"/>
<property name="username" value="${jdbc.SUB.username}"/>
<property name="password" value="${jdbc.SUB.password}"/>
<property name="poolName" value="SUB"/>
<property name="minimumIdle" value="1"/>
<property name="maximumPoolSize" value="1"/>
<property name="autoCommit" value="false"/>
</bean>
<bean id="SUBtransactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="SUBDataSource" />
</bean>
<bean id="SUBtransactionTemplate"
class="org.springframework.transaction.support.TransactionTemplate">
<property name="transactionManager" ref="SUBtransactionManager" />
</bean>
디폴트가 아닌 DB에 대해 데이터를 변경할 때는 또 이에 맞는 접속 정보와 트랜잭션 매니저가 필요하다.
@Transactional(value="SUBtransactionManager", propagation = Propagation.REQUIRES_NEW, rollbackFor = SQLException.class)
위와 같이 @Transactional
애노테이션의 value
값에 해당 DB에 맞는 트랜잭션 매니저를 명시해주고,
기존 트랜잭션과 다른 새로운 트랜잭션이 필요해서 트랜잭션 전파를 REQUIRES_NEW
로 선언해주었다.
어떤 DB와의 커넥션인지, 트랜잭션이 분리되어야 하는지 등의 여부를 생각하면서 코드를 작성하자.