Spring2017.10.14 18:30

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 Atomikos 설정  (0) 2017.10.14
Spring 4 JSR-303 Validator  (0) 2017.06.12
Spring REST Docs 사용법  (0) 2017.04.23
Spring ehcache 설정  (0) 2016.12.12
Posted by 수앙 수앙

댓글을 달아 주세요