Spring全局事务之JTA+Atomikos

本文简单介绍一下在Spring通过声明管理一个有数据库和ActiveMQ参入的全局事务,事务管理器的实现为Atomikos.全局事务的步骤为
1,更新数据库操作.
2访问ActiveMQ资源.
3,提交在数据库A中的操作.
4,提交在ActiveMQ中的操作.
上面的所有步骤应该保证要么全部成功,要么全部回滚.下面是实现的步骤:
1,配置Spring文件:

[html]  view plain copy
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
  4.     xmlns:p="http://www.springframework.org/schema/p"  
  5.     xmlns:aop="http://www.springframework.org/schema/aop"  
  6.     xmlns:tx="http://www.springframework.org/schema/tx"   
  7.     xmlns:jee="http://www.springframework.org/schema/jee"  
  8.     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
  9.     http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd  
  10.     http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd  
  11.     http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd  
  12.     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">   
  13.     <bean id="db1jdbcDAO" class="com.test.spring.tx.xaatomikos.DB1jdbcDAO">  
  14.         <property name="dataSource" ref="xaDataSource" />  
  15.     </bean>     
  16.     <bean id="buzSingleService" class="com.test.spring.tx.xaatomikos.BuzSingleService">  
  17.         <property name="db1jdbcDAO" ref="db1jdbcDAO" />  
  18.         <property name="jmsAccessor" ref="jmsAccessor" />  
  19.     </bean>     
  20.       
  21.     <bean id="xaDataSource"   
  22.       class="com.atomikos.jdbc.AtomikosDataSourceBean"   
  23.       init-method="init" destroy-method="close">   
  24.       <property name="uniqueResourceName"><value>XADBMS</value></property>   
  25.       <property name="xaDataSourceClassName">   
  26.          <value>oracle.jdbc.xa.client.OracleXADataSource</value>   
  27.       </property>   
  28.       <property name="xaProperties">   
  29.         <props>   
  30.             <prop key="user">xxx</prop>   
  31.             <prop key="password">xxx</prop>   
  32.             <prop key="URL">jdbc:oracle:thin:@147.151.240.xx:1521:orcl</prop>   
  33.         </props>   
  34.       </property>      
  35.       <property name="poolSize" value="1"/>   
  36.    </bean>   
  37.       
  38.     <bean id="jmsAccessor" class="com.test.spring.tx.xaatomikos.JmsAccessor">  
  39.         <property name="jmsTemplate" ref="jmsTemplate"/>  
  40.         <property name="destination" ref="destination"/>  
  41.     </bean>  
  42.     <bean id="destination" class="org.apache.activemq.command.ActiveMQQueue">  
  43.         <constructor-arg index="0" value="example.yorker" />  
  44.     </bean>  
  45.     <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">  
  46.        <property name="connectionFactory" ref="atomikosConnectionFactory"/>  
  47.        <property name="defaultDestination" ref="destination"/>  
  48.        <property name="receiveTimeout" value="10000"/>  
  49.        <property name="sessionTransacted" value="true" />  
  50.     </bean>  
  51.       
  52.     <bean id="amqConnectionFactory" class="org.apache.activemq.ActiveMQXAConnectionFactory" >  
  53.         <property name="brokerURL" value="tcp://localhost:61616"/>  
  54.     </bean>   
  55.     <bean id="atomikosConnectionFactory"  
  56.           class="com.atomikos.jms.AtomikosConnectionFactoryBean" init-method="init" destroy-method="close">  
  57.         <property name="uniqueResourceName" value="amq1"/>  
  58.         <property name="xaConnectionFactory" ref="amqConnectionFactory"/>  
  59.     </bean>  
  60.     <!--  
  61.     <bean id="jmsConnectionFactory"  
  62.         class="org.springframework.jms.connection.SingleConnectionFactory">  
  63.         <property name="targetConnectionFactory" ref="atomikosConnectionFactory" />  
  64.     </bean>  
  65.     -->    
  66.     <bean id="atomikosTransactionManager"  
  67.           class="com.atomikos.icatch.jta.UserTransactionManager"  
  68.           init-method="init" destroy-method="close" >  
  69.         <property name="forceShutdown" value="false"/>  
  70.     </bean>  
  71.     <bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp" >  
  72.         <property name="transactionTimeout" value="300"/>  
  73.     </bean>  
  74.     <!--  
  75.     <bean id="userTransactionService" class="com.atomikos.icatch.config.UserTransactionServiceImp"  
  76.         init-method="init" destroy-method="shutdownForce">  
  77.         <constructor-arg>  
  78.             <props>  
  79.                 <prop key="com.atomikos.icatch.service">com.atomikos.icatch.standalone.UserTransactionServiceFactory  
  80.                 </prop>  
  81.             </props>  
  82.         </constructor-arg>  
  83.     </bean>  
  84.     -->  
  85.      <bean id="jtaTransactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">  
  86.         <property name="transactionManager" ref="atomikosTransactionManager"/>  
  87.         <property name="userTransaction" ref="atomikosUserTransaction"/>  
  88.     </bean>   
  89.     <tx:advice id="txAdvice" transaction-manager="jtaTransactionManager">  
  90.         <tx:attributes>  
  91.             <tx:method name="*" propagation="REQUIRED"/>  
  92.         </tx:attributes>  
  93.     </tx:advice>  
  94.     <aop:config>  
  95.         <aop:pointcut id="serviceOperation"  
  96.             expression="execution(* com.test.spring.tx.xaatomikos.*Service*.*(..))" />  
  97.         <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceOperation" />  
  98.     </aop:config>   
  99. </beans>  
2,Java操作数据库的代码Dao

[java]  view plain copy
  1. public class DB1jdbcDAO {  
  2.     private JdbcTemplate jdbcTemplate;    
  3.     public void setDataSource(DataSource dataSource) {  
  4.         this.jdbcTemplate = new JdbcTemplate(dataSource);  
  5.     }  
  6.     public void testInsert(int id, String val) {          
  7.         this.jdbcTemplate.update("insert into A (ID, VAL) values (?, ?)", id, val);  
  8.     }  
3,Java操作MQ的代码JMS accessor:

[java]  view plain copy
  1. public class JmsAccessor {  
  2.     JmsTemplate jmsTemplate;  
  3.     Destination destination;  
  4.     public void send() {  
  5.         MessageCreator messageCreator = new MessageCreator() {  
  6.             public Message createMessage(Session session) {  
  7.                 System.out.println("confactory type:" + jmsTemplate.getConnectionFactory().getClass().getName());  
  8.                 TextMessage message = null;  
  9.                 try {  
  10.                     message = session.createTextMessage("Hello message");  
  11.                 } catch (JMSException e) {  
  12.                     e.printStackTrace();  
  13.                 }  
  14.                 return message;  
  15.             }  
  16.         };  
  17.         jmsTemplate.send(this.destination, messageCreator);  
  18.     }  
  19.   
  20.     public void receive() {  
  21.         System.out.println("confactory type:" + jmsTemplate.getConnectionFactory().getClass().getName());  
  22.         TextMessage message = (TextMessage) jmsTemplate.receive();  
  23.         try {  
  24.             System.out.println("Message received:" + message.getText());  
  25.         } catch (JMSException e) {  
  26.             e.printStackTrace();  
  27.         }  
  28.     }  
  29.     public JmsTemplate getJmsTemplate() {  
  30.         return jmsTemplate;  
  31.     }  
  32.     public void setJmsTemplate(JmsTemplate jmsTemplate) {  
  33.         this.jmsTemplate = jmsTemplate;  
  34.     }  
  35.     public Destination getDestination() {  
  36.         return destination;  
  37.     }  
  38.     public void setDestination(Destination destination) {  
  39.         this.destination = destination;  
  40.     }  
  41. }  
4客户访问端代码:

[java]  view plain copy
  1. public class BuzSingleService {  
  2.     DB1jdbcDAO db1jdbcDAO;  
  3.     JmsAccessor jmsAccessor;  
  4.     public void testTX1() throws Exception {  
  5.         db1jdbcDAO.testInsert(0"db1jdbcDAO val0");  
  6.         jmsAccessor.send();  
  7. ........下面是main 方法中的代码  
  8.         ApplicationContext ctx = new ClassPathXmlApplicationContext("config/xaAtomikosAppcontext.xml");  
  9.         BuzSingleService serv =(BuzSingleService)ctx.getBean("buzSingleService");  
  10.         try {  
  11.             serv.testTX1();   
*一个问题是,在数据库操作和MQ操作都完成后,程序没有退出,不断有如下log输出:

DEBUG 2012-02-16 15:35:37,182 [InactivityMonitor WriteCheck] org.apache.activemq.transport.InactivityMonitor: 10000 ms elapsed since last write check.
DEBUG 2012-02-16 15:35:39,511 [InactivityMonitor WriteCheck] org.apache.activemq.transport.InactivityMonitor: 10000 ms elapsed since last write check.
DEBUG 2012-02-16 15:35:47,183 [InactivityMonitor WriteCheck] org.apache.activemq.transport.InactivityMonitor: 10001 ms elapsed since last write check.

你可能感兴趣的:(Spring全局事务之JTA+Atomikos)