JTA集成JOTM或Atomikos配置分布式事务(Tomcat应用服务器)

buaashang 2010-01-15

一.以下介绍Spring中直接集成JOTM提供JTA事务管理、将JOTM集成到Tomcat中。

(经过测试JOTM在批量持久化时有BUG需要修改源码GenericPool类解决)!

参考文章http://mavin.zhou.blog.163.com/blog/static/114522435200971822334475/

通过集成JOTM,直接在Spring中使用JTA事务

JOTM(JavaOpenTransactionManager)是ObjectWeb的一个开源JTA实现,它本身也是开源应用程序服务器JOnAS(JavaOpenApplicationServer)的一部分,为其提供JTA分布式事务的功能。

Spring2.0附带的依赖类库中虽然包含jotm类库,但是并不完整,你可以到http://jotm.objectweb.org下载完全版的JOTM。

Spring为JOTM提供了一个org.springframework.transaction.jta.JotmFactoryBean支持类,通过该支持类可以方便地创建JOTM本地实例。

1.将jotm的jar包lib目录下所有jar复制到项目中

2.将jotm的jar包conf目录下carol.properties文件复制到项目类路径下,修改内容为:

# do not use CAROL JNDI wrapper      
	carol.start.jndi=false      
		  
	# do not start a name server      
	carol.start.ns=false      
		  
	# Naming Factory   
	carol.jndi.java.naming.factory.url.pkgs=org.apache.naming

3.建立两个数据库,配置两个数据源

<!-- XAPool配置,内部包含了一个XA数据源,对应相应的数据库 -->
   <bean id="mysqlJta" class="org.enhydra.jdbc.pool.StandardXAPoolDataSource" destroy-method="shutdown">  
   <!-- 内部XA数据源-->
        <property name="dataSource"> 
             <bean class="org.enhydra.jdbc.standard.StandardXADataSource" destroy-method="shutdown">  
                 <property name="transactionManager" ref="jotm"/>  
                 <property name="driverName" value="com.mysql.jdbc.Driver"/>  
                 <property name="url" value="jdbc:MySQL://localhost:3309/test"/> 
                 <property name="user" value="root"/>  
                 <property name="password" value=""/>  
             </bean>  
         </property>  
         <property name="user" value="root"/>  
         <property name="password" value=""/>  
     </bean>  

   <bean id="oracleJta" class="org.enhydra.jdbc.pool.StandardXAPoolDataSource" destroy-method="shutdown">  
        <property name="dataSource"> 
             <bean class="org.enhydra.jdbc.standard.StandardXADataSource" destroy-method="shutdown">  
                 <property name="transactionManager" ref="jotm"/>  
                 <property name="driverName" value="oracle.jdbc.driver.OracleDriver"/>  
                 <property name="url" value="jdbc:oracle:thin:@localhost:1521:orcl"/>  
			        <property name="user" value="orcl"/>  
			        <property name="password" value=""/>                   
             </bean>  
         </property>  
         <property name="user" value="orcl"/>  
         <property name="password" value=""/>  
     </bean>
4.事务配置
<!-- JOTM本地实例 -->
	<bean id="jotm" class="org.springframework.transaction.jta.JotmFactoryBean" />	

	<!-- JTA事务管理器 -->
	<bean id="txManager" class="org.springframework.transaction.jta.JtaTransactionManager">
		<property name="userTransaction" ref="jotm"/>
	</bean>	

	<!-- JTA事务传播特性 -->
	<tx:advice id="txAdviceJta" transaction-manager="txManager">
		<tx:attributes>
         <tx:method name="Jta*"     isolation="DEFAULT" propagation="REQUIRED" rollback-for="Exception"/>
         <tx:method name="*" read-only="true"/> 
		</tx:attributes>
	</tx:advice>
	
	<aop:config>
		<aop:advisor pointcut="execution(* com.xxxxl.service.impl..*(..))"   advice-ref="txAdviceJta" />
	</aop:config>

	<bean id="timerDaoMysql" class="com.xxxxl.TimerDaoImpl" scope="prototype">
		<property name="dataSource" ref="mysqlJta"></property>
	</bean>
	<bean id="timerDaoOracle" class="com.xxxxl.TimerDaoImpl" scope="prototype">
		<property name="dataSource" ref="oracleJta"></property>
	</bean>

二.以下介绍Spring中直接集成Atomikos提供JTA事务管理、将Atomikos集成到Tomcat中。(经过测试推荐此方法)

AtomikosTransactionsEssentials现在的版本是3.1.7,可以在http://www.atomikos.com/Main/TransactionsEssentialsDownloadForm下载,在发布包里的examples文件夹下面有些例子,非常实用,我在使用中参考里面的例子很容易配置成功。1.将Atomikos的jar包dist目录下所有jar复制到项目中

2.建立两个数据库,配置两个数据源。

Atomikos数据源配置方法有三种分别有:SimpleDataSourceBean,AtomikosDataSourceBean,AtomikosNonXADataSourceBean可任选一种

<!-- Simple表示基础数据库连接配置 -->
	 <bean id="oracleJta" class="com.atomikos.jdbc.SimpleDataSourceBean" init-method="init" destroy-method="close">   
        <property name="uniqueResourceName">   
            <value>OracleXADataSource</value>   <!--任意命名,但必须唯一-->
        </property>   
        <property name="xaDataSourceClassName">   
            <value>oracle.jdbc.xa.client.OracleXADataSource</value>   
        </property>   
        <property name="xaDataSourceProperties">   
            <value>URL=jdbc:oracle:thin:@localhost:1521:orcl;user=orcl;password=</value>   
        </property>   
        <property name="exclusiveConnectionMode">   
            <value>true</value>   
        </property>   
        <property name="connectionPoolSize">   
            <value>3</value>   
        </property>   
        <property name="validatingQuery">   
            <value>SELECT 1</value>   
        </property>   
    </bean>   
    <!-- Atomikos表示必须要用到XA数据库驱动类,可设置连接池(经过测试推荐此方法) -->
	<bean id="oracleJta" class="com.atomikos.jdbc.AtomikosDataSourceBean" init-method="init" destroy-method="close" lazy-init="true">  
        <property name="uniqueResourceName">  
            <value>OracleXADataSource</value>  
        </property>  
        <property name="xaDataSourceClassName">  
            <value>oracle.jdbc.xa.client.OracleXADataSource</value>  
        </property>
        <property name="xaProperties">  
            <props>  
					 <prop key="URL">jdbc:oracle:thin:@localhost:1521:orcl</prop>  
                <prop key="user">orcl</prop>  
                <prop key="password"></prop>  
            </props>  
        </property>  
		  <property name="poolSize"><value>1</value></property>    
		  <property name="maxPoolSize"><value>30</value></property>
          <property name="testQuery" value="SELECT 1 from dual"/>  <!--解决偶尔失去连接的bug-->      
    </bean> 	
    <!-- AtomikosNon表示必须要用到普通数据库驱动类,可设置连接池 -->       
	<bean id="oracleJta" class="com.atomikos.jdbc.nonxa.AtomikosNonXADataSourceBean">
		<property name="uniqueResourceName"><value>OracleXADataSource</value></property>
		<property name="user"><value>orcl</value></property>
		<property name="password"><value></value></property>
		<property name="url"><value>jdbc:oracle:thin:@192.168.1.217:1521:orcl</value></property>
		<property name="driverClassName"><value>oracle.jdbc.OracleDriver</value></property>
		<property name="poolSize"><value>1</value></property>
		<property name="borrowConnectionTimeout"><value>60</value></property>
	</bean>	
	另外一个数据库在这就不在写了,设置同上只是mysql的驱动类名为:xaDataSourceClassName:com.mysql.jdbc.jdbc2.optional.MysqlXADataSource

3.事务配置

<!-- Atomikos事务方法 -->      
    <bean id="atomikosTransactionManager"  
        class="com.atomikos.icatch.jta.UserTransactionManager"  
        init-method="init" destroy-method="close">  
        <property name="forceShutdown">  
            <value>true</value>  
        </property>  
    </bean>  
    <bean id="atomikosUserTransaction"  
        class="com.atomikos.icatch.jta.UserTransactionImp">  
        <property name="transactionTimeout" value="240" />  
    </bean>  
    <bean id="transactionManager"  
        class="org.springframework.transaction.jta.JtaTransactionManager">  
        <property name="transactionManager">  
            <ref bean="atomikosTransactionManager" />  
        </property>  
        <property name="userTransaction">  
            <ref bean="atomikosUserTransaction" />  
        </property>  
    </bean> 
	接下来的代码和上例类同就不再写。

相关推荐