DataSource와 트랜잭션 매니저

szlee·2024년 1월 3일
0

SpringDB

목록 보기
8/12
  • DataSource : 커넥션을 획득하는 방법을 추상화. DB와의 커넥션을 가져옴
    업로드중..
  • 커넥션 풀 : 커넥션을 미리 생성해두고 사용. 커넥션 조회 -> 획득 -> 사용 -> 반환

    • ex) hikariCP

  • 트랜잭션 매니저 : 트랜잭션 관리해주는 애. 스프링 트랜잭션 추상화. 트랜잭션을 시작하려면 커넥션이 필요하다. 트랜잭션 매니저는 데이터소스를 통해 커넥션을 만들고 트랜잭션을 시작한다.









업무를 하다가 서비스단의 특정 메서드에서 @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와의 커넥션인지, 트랜잭션이 분리되어야 하는지 등의 여부를 생각하면서 코드를 작성하자.

profile
🌱

0개의 댓글