본문 바로가기
Spring

Spring 4 Atomikos 설정

by 수앙 2017. 10. 14.

Spring Framework 4.3.11 기준으로 Atomikos 4.0.4 설정 방법을 알아보겠다.

Atomikos와 관련있는 Spring 설정만 알아본다.

 

Atomikos 홈페이지는 아래 링크이다.

https://www.atomikos.com

유료 버전과 무료 버전이 존재하는데 차이점은 하위 버전과 기술지원을 받을 수 있는 차이가 있는 것 같다.

자세한 건 홈페이지에서 확인하기 바란다.

 

아래 예제의 패키지명 등 각 설정값들은 임의로 넣음

트랜잭션 방식은 @Transactional 어노테이션을 사용

 

메이븐 pom.xml

<!-- myBatis -->
<dependency>
	<groupId>org.mybatis</groupId>
	<artifactId>mybatis</artifactId>
	<version>3.4.5</version>
</dependency>
<dependency>
	<groupId>org.mybatis</groupId>
	<artifactId>mybatis-spring</artifactId>
	<version>1.3.1</version>
</dependency>
<!-- MariaDB JDBC -->
<dependency>
	<groupId>org.mariadb.jdbc</groupId>
	<artifactId>mariadb-java-client</artifactId>
	<version>1.6.5</version>
</dependency>
<!-- Atomikos -->
<dependency>
	<groupId>com.atomikos</groupId>
	<artifactId>transactions-jta</artifactId>
	<version>4.0.4</version>
</dependency>
<dependency>
	<groupId>com.atomikos</groupId>
	<artifactId>transactions-jdbc</artifactId>
	<version>4.0.4</version>
</dependency>
<dependency>
	<groupId>javax.transaction</groupId>
	<artifactId>jta</artifactId>
	<version>1.1</version>
</dependency>

 

Spring xml 설정

컨트롤러를 제외한 component-scan은 web.xml의 contextConfigLocation에 지정한 xml 파일에서 해야 함

그렇지 않으면 트랜잭션이 수행 안됨

<context:component-scan base-package="com.my.app">
	<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>

 

Spring Atomikos 설정

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:mybatis-spring="http://mybatis.org/schema/mybatis-spring"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring-1.2.xsd
                           http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
                           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
 
    <!-- Atomikos 설정 start -->
    <bean id="userTransactionService" class="com.atomikos.icatch.config.UserTransactionServiceImp" init-method="init" destroy-method="shutdownForce">
        <constructor-arg>
            <props>
                <prop key="com.atomikos.icatch.service">
                    com.atomikos.icatch.standalone.UserTransactionServiceFactory
                </prop>
            </props>
        </constructor-arg>
    </bean>
    
    <!-- Construct Atomikos UserTransactionManager, needed to configure Spring -->
    <bean id="atomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager" init-method="init" destroy-method="close" depends-on="userTransactionService">
        <property name="startupTransactionService" value="false" />
        <property name="forceShutdown" value="false" />
    </bean>
    
    <bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp" depends-on="userTransactionService">
        <property name="transactionTimeout" value="300" />
    </bean>
    
    <!-- JTA 트랜잭션 설정 -->
    <bean id="jtaTransactionManager" class="org.springframework.transaction.jta.JtaTransactionManager" depends-on="userTransactionService">
        <property name="transactionManager" ref="atomikosTransactionManager" />
        <property name="userTransaction" ref="atomikosUserTransaction" />
    </bean>
    
    <!-- @Transactional 사용 설정 -->
    <tx:annotation-driven transaction-manager="jtaTransactionManager" />
    
    <!-- DataSource1 설정 -->
    <bean id="testDataSource" class="com.atomikos.jdbc.AtomikosDataSourceBean">
        <property name="uniqueResourceName" value="test" />
        <property name="xaDataSourceClassName" value="org.mariadb.jdbc.MariaDbDataSource" />
        <property name="xaProperties">
            <props>
                <prop key="url">jdbc:mariadb://localhost:3306/test</prop>
                <prop key="user">test</prop>
                <prop key="password">test</prop>
            </props>
        </property>
        <property name="poolSize" value="50" />
    </bean>
    
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="testDataSource" />
        <property name="mapperLocations" value="classpath*:mappers/mariadb/test/**/*.xml" />
        <property name="configuration">
            <bean class="org.apache.ibatis.session.Configuration">
                <property name="mapUnderscoreToCamelCase" value="true" />
            </bean>
        </property>
    </bean>
    
    <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
        <constructor-arg index="0" ref="sqlSessionFactory" />
    </bean>
    
    <mybatis-spring:scan base-package="com.my.app.test.*.mapper" factory-ref="sqlSessionFactory" template-ref="sqlSession" />
    
    <!-- DataSource2 설정 -->
    <bean id="testDataSource2" class="com.atomikos.jdbc.AtomikosDataSourceBean">
        <property name="uniqueResourceName" value="test2" />
        <property name="xaDataSourceClassName" value="org.mariadb.jdbc.MariaDbDataSource" />
        <property name="xaProperties">
            <props>
                <prop key="url">jdbc:mariadb://localhost:3306/test2</prop>
                <prop key="user">test2</prop>
                <prop key="password">test2</prop>
            </props>
        </property>
        <property name="poolSize" value="50" />
    </bean>
    
    <bean id="sqlSessionFactory2" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="testDataSource2" />
        <property name="mapperLocations" value="classpath*:mappers/mariadb/test2/**/*.xml" />
        <property name="configuration">
            <bean class="org.apache.ibatis.session.Configuration">
                <property name="mapUnderscoreToCamelCase" value="true" />
            </bean>
        </property>
    </bean>
    
    <bean id="sqlSession2" class="org.mybatis.spring.SqlSessionTemplate">
        <constructor-arg index="0" ref="sqlSessionFactory2" />
    </bean>
    
    <mybatis-spring:scan base-package="com.my.app.test2.*.mapper" factory-ref="sqlSessionFactory2" template-ref="sqlSession2" />
    
</beans>

 

Spring Service 클래스

@Service
public class xxxService {

    @Transactional
    public int insert() {
        ...
    }

}

 

그럼 아래와 같이 로그가 찍힘

아래 로그 내용은 서로 다른 DB에서 insert가 수행됐는데

첫 번째 insert는 성공했고 두 번째 insert는 실패하여

첫 번째, 두 번째 트랜잭션이 동시에 롤백되는 로그이다.

[http-nio-8080-exec-3] DEBUG o.s.t.jta.JtaTransactionManager - Creating new transaction with name [com.my.app.test.user.service.UserService.insertUser]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; ''

[http-nio-8080-exec-3] DEBUG c.a.i.i.CompositeTransactionManagerImp - createCompositeTransaction ( 10000 ): created new ROOT transaction with id 192.168.1.105.tm150817196160700002

[http-nio-8080-exec-3] DEBUG c.a.jdbc.AbstractDataSourceBean - AtomikosDataSoureBean 'test': getConnection()...

[http-nio-8080-exec-3] INFO  c.a.jdbc.AbstractDataSourceBean - AtomikosDataSoureBean 'test': init...

[http-nio-8080-exec-3] DEBUG c.a.jdbc.AtomikosConnectionProxy - atomikos connection proxy for org.mariadb.jdbc.MariaDbConnection@52529bf6: calling getAutoCommit...

[http-nio-8080-exec-3] DEBUG c.m.a.t.u.m.UserMapper.insertUser - ==>  Preparing: insert into user (user_id, user_name) values(?, ?) 

[http-nio-8080-exec-3] DEBUG c.a.i.imp.CompositeTransactionImp - addParticipant ( XAResourceTransaction: 3139322E3136382E312E3130352E746D313530383137313936313630373030303032:3139322E3136382E312E3130352E746D33 ) for transaction 192.168.1.105.tm150817196160700002

[http-nio-8080-exec-3] DEBUG c.a.d.xa.XAResourceTransaction - XAResource.start ( 3139322E3136382E312E3130352E746D313530383137313936313630373030303032:3139322E3136382E312E3130352E746D33 , XAResource.TMNOFLAGS ) on resource test represented by XAResource instance org.mariadb.jdbc.MariaXaResource@5dc43247

[http-nio-8080-exec-3] DEBUG c.a.i.imp.CompositeTransactionImp - registerSynchronization ( com.atomikos.jdbc.AtomikosConnectionProxy$JdbcRequeueSynchronization@48499297 ) for transaction 192.168.1.105.tm150817196160700002

[http-nio-8080-exec-3] DEBUG c.a.jdbc.AtomikosConnectionProxy - atomikos connection proxy for org.mariadb.jdbc.MariaDbConnection@52529bf6: calling prepareStatement(insert into user (user_id, user_name) values(?, ?))...

[http-nio-8080-exec-3] DEBUG c.m.a.t.u.m.UserMapper.insertUser - ==> Parameters: test1(String), 테스트1(String)

[http-nio-8080-exec-3] DEBUG c.m.a.t.u.m.UserMapper.insertUser - <==    Updates: 1

[http-nio-8080-exec-3] DEBUG c.a.jdbc.AbstractDataSourceBean - AtomikosDataSoureBean 'test2': getConnection()...

[http-nio-8080-exec-3] INFO  c.a.jdbc.AbstractDataSourceBean - AtomikosDataSoureBean 'test2': init...

[http-nio-8080-exec-3] DEBUG c.a.jdbc.AtomikosConnectionProxy - atomikos connection proxy for org.mariadb.jdbc.MariaDbConnection@57da83a7: calling getAutoCommit...

[http-nio-8080-exec-3] DEBUG c.m.a.t.u.m.User2Mapper.insertUser - ==>  Preparing: insert into user (user_id, user_name) values(?, ?) 

[http-nio-8080-exec-3] DEBUG c.a.i.imp.CompositeTransactionImp - addParticipant ( XAResourceTransaction: 3139322E3136382E312E3130352E746D313530383137313936313630373030303032:3139322E3136382E312E3130352E746D34 ) for transaction 192.168.1.105.tm150817196160700002

[http-nio-8080-exec-3] DEBUG c.a.d.xa.XAResourceTransaction - XAResource.start ( 3139322E3136382E312E3130352E746D313530383137313936313630373030303032:3139322E3136382E312E3130352E746D34 , XAResource.TMNOFLAGS ) on resource test2 represented by XAResource instance org.mariadb.jdbc.MariaXaResource@7d6a9358

[http-nio-8080-exec-3] DEBUG c.a.i.imp.CompositeTransactionImp - registerSynchronization ( com.atomikos.jdbc.AtomikosConnectionProxy$JdbcRequeueSynchronization@48499297 ) for transaction 192.168.1.105.tm150817196160700002

[http-nio-8080-exec-3] DEBUG c.a.jdbc.AtomikosConnectionProxy - atomikos connection proxy for org.mariadb.jdbc.MariaDbConnection@57da83a7: calling prepareStatement(insert into user (user_id, user_name) values(?, ?))...

[http-nio-8080-exec-3] DEBUG c.m.a.t.u.m.User2Mapper.insertUser - ==> Parameters: test2(String), 테스트2(String)

[http-nio-8080-exec-3] DEBUG c.a.jdbc.AtomikosConnectionProxy - atomikos connection proxy for org.mariadb.jdbc.MariaDbConnection@52529bf6: close()...

[http-nio-8080-exec-3] DEBUG c.a.d.xa.XAResourceTransaction - XAResource.end ( 3139322E3136382E312E3130352E746D313530383137313936313630373030303032:3139322E3136382E312E3130352E746D33 , XAResource.TMSUCCESS ) on resource test represented by XAResource instance org.mariadb.jdbc.MariaXaResource@5dc43247

[http-nio-8080-exec-3] DEBUG c.a.jdbc.AtomikosConnectionProxy - atomikos connection proxy for org.mariadb.jdbc.MariaDbConnection@57da83a7: close()...

[http-nio-8080-exec-3] DEBUG c.a.d.xa.XAResourceTransaction - XAResource.end ( 3139322E3136382E312E3130352E746D313530383137313936313630373030303032:3139322E3136382E312E3130352E746D34 , XAResource.TMSUCCESS ) on resource test2 represented by XAResource instance org.mariadb.jdbc.MariaXaResource@7d6a9358

[http-nio-8080-exec-3] DEBUG o.s.t.jta.JtaTransactionManager - Initiating transaction rollback

[http-nio-8080-exec-3] DEBUG c.a.d.xa.XAResourceTransaction - XAResource.rollback ( 3139322E3136382E312E3130352E746D313530383137313936313630373030303032:3139322E3136382E312E3130352E746D33 ) on resource test represented by XAResource instance org.mariadb.jdbc.MariaXaResource@5dc43247

[http-nio-8080-exec-3] DEBUG c.a.d.xa.XAResourceTransaction - XAResource.rollback ( 3139322E3136382E312E3130352E746D313530383137313936313630373030303032:3139322E3136382E312E3130352E746D34 ) on resource test2 represented by XAResource instance org.mariadb.jdbc.MariaXaResource@7d6a9358

[http-nio-8080-exec-3] DEBUG c.a.i.imp.CompositeTransactionImp - rollback() done of transaction 192.168.1.105.tm150817196160700002

[http-nio-8080-exec-3] DEBUG c.a.i.imp.CompositeTransactionImp - rollback() done of transaction 192.168.1.105.tm150817196160700002

 

끝.

'Spring' 카테고리의 다른 글

Spring 4.3 Redis Sentinel Pubsub 설정  (0) 2018.06.16
Spring 4.3 Redis Sentinel 연동  (0) 2018.06.16
Spring 4 JSR-303 Validator  (0) 2017.06.12
Spring REST Docs 사용법  (0) 2017.04.23
Spring ehcache 설정  (0) 2016.12.12

댓글