struts2+spring3.2.9+hibernate4.2.0+atomikos3.8实现分布式事务JTA

         目前开发的J2EE系统用到了两个数据源,需要分布式事物(JTA)的支持,但是tomcat不支持JTA,开发调试不太方便,本文通过使用atomikos实现了分布式事务的支持,理论可以运行在任何java容器中。

一、将以下jar包放到lib目录下

二、将配置文件jta.properties放到WEB-INF目录下,内容如下:

三、修改spring配置文件,建立2个数据源:

<bean id="dataSource" class="com.atomikos.jdbc.AtomikosDataSourceBean"  init-method="init" destroy-method="close">  
                <description>oracle xa datasource</description>  
                <property name="uniqueResourceName">  
                    <value>oracle_ds</value>  
                </property>  
                <property name="xaDataSourceClassName">  
                    <value>${jdbc.XADriverClassName}</value>  
                </property>  
                <property name="xaProperties">  
                    <props>  
                        <prop key="user">${jdbc.username}</prop>  
                        <prop key="password">${jdbc.password}</prop>  
                        <prop key="URL">${jdbc.url}</prop>  
                    </props>  
                </property>  
                 <property name="minPoolSize" value="5" />  
                   <property name="maxPoolSize" value="100" />  
                    <property name="borrowConnectionTimeout" value="30" />  
                    <property name="testQuery" value="select 1 from dual " />  
                   <property name="maintenanceInterval" value="60" />
    </bean>
    
    <bean id="dataSourceForAdmin" class="com.atomikos.jdbc.AtomikosDataSourceBean"  init-method="init" destroy-method="close">  
                <description>oracle xa datasource</description>  
                <property name="uniqueResourceName">  
                    <value>oracle_ds_admin</value>  
                </property>  
                <property name="xaDataSourceClassName">  
                    <value>${admin.jdbc.XADriverClassName}</value>  
                </property>  
                <property name="xaProperties">  
                    <props>  
                        <prop key="user">${admin.jdbc.username}</prop>  
                        <prop key="password">${admin.jdbc.password}</prop>  
                        <prop key="URL">${admin.jdbc.url}</prop>  
                    </props>  
                </property>  
               
                 <property name="minPoolSize" value="5" />  
                   <property name="maxPoolSize" value="100" />  
                    <property name="borrowConnectionTimeout" value="30" />  
                    <property name="testQuery" value="select 1 from dual" />  
                   <property name="maintenanceInterval" value="60" />
    </bean>

<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="hibernateProperties">  
            <props>
                
                <prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.format_sql">false</prop>
                <prop key="hibernate.current_session_context_class">jta</prop>
                <prop key="hibernate.transaction.factory_class">org.hibernate.transaction.JTATransactionFactory</prop>
            </props>
       </property>
       <property name="packagesToScan" value="com.domain"/>

    </bean>
    <bean id="sessionFactoryForAdmin" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSourceForAdmin" />
        <property name="hibernateProperties">  
            <props>
                
                <prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.format_sql">false</prop>
                <prop key="hibernate.current_session_context_class">jta</prop>
                <prop key="hibernate.transaction.factory_class">org.hibernate.transaction.JTATransactionFactory</prop>
            </props>
       </property>
       <property name="packagesToScan" value="com.domain"/>

    </bean>


    <bean id="atomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager"  
                init-method="init" destroy-method="close">  
                <description>UserTransactionManager</description>  
                <property name="forceShutdown">  
                    <value>true</value>  
                </property>  
    </bean>
            
    <bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp">  
                <property name="transactionTimeout" value="300" />  
    </bean>
    
    <bean id="txManager"   class="org.springframework.transaction.jta.JtaTransactionManager">  
                <property name="transactionManager">  
                    <ref bean="atomikosTransactionManager" />  
                </property>  
                <property name="userTransaction">  
                    <ref bean="atomikosUserTransaction" />  
                </property>  
    </bean>

    
    
    <!-- 配置事务切面 -->
    <tx:advice id="txAdvice" transaction-manager="txManager">
        <tx:attributes>
            <tx:method name="get*" propagation="REQUIRED"  read-only="true"/>
            <tx:method name="find*" propagation="REQUIRED"  read-only="true"/>
            <tx:method name="query*" propagation="REQUIRED"  read-only="true"/>
            <tx:method name="select*" propagation="REQUIRED"  read-only="true"/>
            <tx:method name="save*" propagation="REQUIRED"/>
            <tx:method name="add*" propagation="REQUIRED"/>
            <tx:method name="delete*" propagation="REQUIRED"/>
            <tx:method name="del*" propagation="REQUIRED"/>
            <tx:method name="update*" propagation="REQUIRED"/>
            <tx:method name="execute*" propagation="REQUIRED"/>
            <tx:method name="exec*" propagation="REQUIRED"/>
            <tx:method name="*" propagation="REQUIRED"    read-only="true"/>
        </tx:attributes>
    </tx:advice>

四、oracle数据源的支持:

这里使用的是oracle10g,需要使用支持XA数据源的驱动,这里为 ojdbc14.jar 或者ojdbc6.jar 均可;

配置如下,注意和单数据源驱动类名称区别


五、dao和不同sessionfactory关联:

<bean id="answerQueryDao" class="com.dao.impl.AnswerQueryDaoImpl" scope="singleton">
         
        <property name="sessionFactory">
            <ref bean="sessionFactory"/>
        </property>
            
    </bean>

<bean id="adminLoginTokenDao" class="com.dao.impl.AdminLoginTokenDaoImpl" scope="singleton">
        
        <property name="sessionFactory">
            <ref bean="sessionFactoryForAdmin"/>
        </property>
            
    </bean>

六、只能使用openSession来获取session,不能通过getCurrentSession获取,并且要调用flush方法才能使增加删除修改操作生效如下:

七、测试成功,供需要的同行参考一下,不妥之处,还请网友拍砖。


你可能感兴趣的:(spring,oracle,Hibernate,jta,atomikos)