목차 >> Transaction Manager(tx) 
+- GlueTransactionManager  
----+- Service Layer에서의 트랜잭션  
----+- Activity Layer에서의 트랜잭션  
+- GlueDataSourceTransactionManager  
+- GlueLazyDataSourceTransactionManager  
+- GlueHibernateTransactionManager

7장 Transaction Manager(tx)

이번 장에서 다루는 Transaction Manager는 이전 장의 Data Access Object(DAO)와 같이 사용됩니다.

GlueTransactionManager

GlueTransactionManager는 트랜잰선 관리 interface입니다. GlueTransactionManager에서 제공하는 메소드는 Java Doc을 참고합니다 (GlueAPI).

그림 : GlueTransactionManager
GlueTransactionManager

Transaction Manager는 dao와 한쌍으로 applicationContext.xml에 정의합니다.

<bean id="dao" class=. . . />
<bean id="tx" class=. . . />

Service Layer에서의 트랜잭션

Glue Service에서 dao가 사용되는 경우 다음과 같이 <transaction-manager>가 추가되어 있어야 DB에 대한 트랜잭션(commit)이 반영됩니다.

<?xml version="1.0" encoding="UTF-8"?>
<service name="hello-service" initial="HelloActivity" xmlns="http://www.poscoict.com/glueframework/service">
    <transaction-manager id="tx" commit="true"/>
    <activity . . ./>
</service>

transaction-manager 은 다음 속성을 필요로 합니다.

  • id : Spring의 applicationContext.xml에 정의 되어 있는 Transaction Manager의 ID
  • commit: 해당 Transaction을 commit 할 지에 대한 여부. SubService의 경우 MainService의 Transaction을 사용하고 실제 Commit을 하지 않을 경우 “false”로 정의 하거나 service에 Transaction을 등록하지 않아야 한다.

Activity Layer에서의 트랜잭션

GlueActivity의 JavaDoc에는 다음과 같은 Method가 있습니다 (GlueAPI 참고).

  • void commitTransaction(String transactionMgrKey)
  • void rollbackTransaction(String transactionMgrKey)
    public class SampleActivity extends GlueActivity<GlueContext> {
        @Override
        public String runActivity( GlueContext ctx )
        {
            . . .
            /* activity가 속한 service.xml 의 transaction-manager의 id 값 */
            String transactionMgrKey = "tx";
            try
            {
                this.commitTransaction(transactionMgrKey);
            . . .
            } catch ( Exception ex ) { 
                this.rollbackTransaction(transactionMgrKey)
            . . .
            }
            return GlueBizControlConstants.SUCCESS;
        }
    }
    

GlueBizController는 Glue Service를 실행할 때, 등록되어 있는 <transaction-manager>를 기준으로 Transaction들을 Start합니다. Glue Service가 정상 종료 하였을 경우에는 start된 Transaction들을 Commit하고 Exception이 발생한 경우에는 start된 Transaction들을 Rollback합니다.
Transaction의 관리(start,commit,rollback)은 Service Layer에서 처리되는 것이 기본 원칙이므로, Activity Layer에서 Commit혹은 Rollback 이 필요한 경우에는 GlueActivity에서 제공하는 2개의 메소드를 사용합니다. 이 때 메소드의 인자는 Glue Service에 등록되어 있는 <transaction-manager>를 사용하여야 합니다.

GlueService에 등록되어 있는 <transaction-manager>를 얻어와서, Transaction처리가 가능한지 확인하는 방법은 아래와 같습니다. (ver glue-core-4.2.7-RELEASE 부터 지원)

public class SampleActivity extends GlueActivity<GlueContext> {
    @Override
    public String runActivity( GlueContext ctx )
    {
        . . .
        /* activity가 속한 service.xml 의 transaction-manager의 id 값 */
        String transactionMgrKey = "tx";

        GlueService service = (GlueService) ctx.get( (String) ctx.get( GlueBizControlConstants.SERVICE_NAME ) );
        if ( service.getTransactionManagers().containsKey( transactionMgrKey ) )
        {
            try
            {
                this.commitTransaction(transactionMgrKey);
            . . .
            } catch ( Exception ex ) { 
                this.rollbackTransaction(transactionMgrKey)
            . . .
            }
        }else{
            /* activity가 subservice 에 속할 경우, 경우에 따라 commit, rollback 사용 가능  */
        }
        return GlueBizControlConstants.SUCCESS;
    }
}

GlueDataSourceTransactionManager

GlueDataSourceTransactionManager의 상속관계 및 메소드는 Java Doc을 참고합니다 (GlueAPI).

GlueDataSourceTransactionManager의 속성(property)는 다음과 같습니다.

  • dataSource : 참조할 DataSource Bean. 필수.
    <bean id="tx" class="com.poscoict.glueframework.transaction.GlueDataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    
  • transactionDefinition : 참조할 Transaction Definition. 선택.
    <bean id="tx" class="com.poscoict.glueframework.transaction.GlueDataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
        <property name="transactionDefinition" ref="tx-def"/>
    </bean>
    <bean id="txDef" class="com.poscoict.glueframework.transaction.GlueDefaultTransactionDefinition">
        <property name="isolationLevelName" value="ISOLATION_DEFAULT"/>
        <property name="propagationBehaviorName" value="PROPAGATION_REQUIRED_NEW"/>
        <property name="readOnly" value="false"/>
        <property name="timeout" value="100"/>
    </bean>
    
그림 : GlueDataSourceTransactionManager
GlueDataSourceTransactionManager

DAO와의 관계

  • GlueJdbcDao를 사용할 경우의 applicationContext.xml은 다음과 같이 구성합니다.
    <bean id="dao" class="com.poscoict.glueframework.dao.GlueJdbcDao">
        <property name="dataSource" ref="dataSource"/>
        <property name="queryManager" ref="queryManager"/>
    </bean>
    <bean id="tx" class="com.poscoict.glueframework.transaction.GlueDataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <bean id="dataSource" class= . . . />
    <bean id="queryManager" class= . . . />
    
  • GlueMybatisDao를 사용할 경우의 applicationContext.xml은 다음과 같이 구성합니다.
    <bean id="dao" class="com.poscoict.glueframework.dao.mybatis.GlueMybatisDao">
        <property name="sqlSession" ref="sqlSession" />
    </bean>
    <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
        <constructor-arg index="0" ref="sqlSessionFactory" />
    </bean>
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="mapperLocations" value="classpath*:mybatis/mapper/*.xml" />
    </bean>
    <bean id="tx" class="com.poscoict.glueframework.transaction.GlueDataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <bean id="dataSource" class= . . . />
    

GlueLazyDataSourceTransactionManager

GlueLazyDataSourceTransactionManager의 상속관계 및 메소드는 Java Doc을 참고합니다 (GlueAPI).

GlueLazyDataSourceTransactionManager의 속성(property)는 다음과 같습니다.

  • dataSource : 참조할 DataSource Bean. 필수.
    <bean id="tx" class="com.poscoict.glueframework.transaction.GlueLazyDataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    
  • transactionDefinition : 참조할 Transaction Definition. 선택.
    <bean id="tx" class="com.poscoict.glueframework.transaction.GlueLazyDataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
        <property name="transactionDefinition" ref="tx-def"/>
    </bean>
    <bean id="txDef" class="com.poscoict.glueframework.transaction.GlueDefaultTransactionDefinition">
        <property name="isolationLevelName" value="ISOLATION_DEFAULT"/>
        <property name="propagationBehaviorName" value="PROPAGATION_REQUIRED_NEW"/>
        <property name="readOnly" value="false"/>
        <property name="timeout" value="100"/>
    </bean>
    
그림 : GlueLazyDataSourceTransactionManager
GlueLazyDataSourceTransactionManager

다음은 GlueService 없이 사용하는 Java Code 예시입니다.

GlueLazyTransactionManager tx = GlueStaticContext.getBeanFactory().getBeanObject("tx", GlueLazyTransactionManager.class);
tx.startTransaction();
boolean isError = . . . ;
. . .

if ( isError ) {
    tx.lazyRollback();
}else{
    tx.lazyCommit();
}

다음은 Activity Layer에서의 Java Code 예시입니다.

public class CustomActivity extends GlueActivity{
    public String runActivity( GlueContext ctx )
        GlueLazyTransactionManager tx = GlueStaticContext.getBeanFactory().getBeanObject("tx", GlueLazyTransactionManager.class);
        boolean isError = . . . ;
        . . .
        
        if ( isError ) {
            tx.lazyRollback();
        }else{
            tx.lazyCommit();
        }
        tx.startTransaction();
        return GlueBizControlConstants.SUCCESS;
    }
}

DAO와의 관계

  • GlueLazyJdbcDao를 사용할 경우의 applicationContext.xml은 다음과 같이 구성합니다.
    <bean id="dao" class="com.poscoict.glueframework.dao.GlueLazyJdbcDao">
        <property name="dataSource" ref="dataSource"/>
        <property name="queryManager" ref="queryManager"/>
        <property name="fetchSize" ... />
        <property name="countQuery" ... />
    </bean>
    <bean id="tx" class="com.poscoict.glueframework.transaction.GlueLazyDataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <bean id="dataSource" class= . . . />
    <bean id="queryManager" class= . . . />
    

GlueHibernateTransactionManager

GlueHibernateTransactionManager의 상속관계 및 메소드는 Java Doc을 참고합니다 (GlueAPI).

GlueDataSourceTransactionManager의 속성(property)는 다음과 같습니다.

  • sessionFactory : 참조할 SessionFactory Bean. 필수.
    <bean id="tx" class="com.poscoict.glueframework.transaction.GlueHibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>
    
그림 : GlueHibernateTransactionManager
GlueHibernateTransactionManager

DAO와의 관계

  • GlueHibernateDao를 사용할 경우의 applicationContext.xml은 다음과 같이 구성합니다.
    <bean id="dao" class="com.poscoict.glueframework.dao.hibernate.GlueHibernateDao">
        <property name="sessionFactory" ref="sessionFactory"/>
        <property name="queryManager" ref="queryManager"/>
    </bean>
    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="mappingResources">
            <list>
                <value>scott.hbm.xml</value>
            </list>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.HSQLDialect</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.transaction.flush_before_completion">false</prop>
            </props>
        </property>
    </bean>
    <bean id="tx" class="com.poscoict.glueframework.transaction.GlueHibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>
    <bean id="dataSource" class=. . . />
    <bean id="queryManager" class= . . . />