Spring全局事务之JTA+Atomikos

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

<?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:p="http://www.springframework.org/schema/p"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:tx="http://www.springframework.org/schema/tx" 
	xmlns:jee="http://www.springframework.org/schema/jee"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
	http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
	http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">	
	<bean id="db1jdbcDAO" class="com.test.spring.tx.xaatomikos.DB1jdbcDAO">
		<property name="dataSource" ref="xaDataSource" />
	</bean>	
	<bean id="buzSingleService" class="com.test.spring.tx.xaatomikos.BuzSingleService">
		<property name="db1jdbcDAO" ref="db1jdbcDAO" />
		<property name="jmsAccessor" ref="jmsAccessor" />
	</bean>	
	
	<bean id="xaDataSource" 
      class="com.atomikos.jdbc.AtomikosDataSourceBean" 
      init-method="init" destroy-method="close"> 
      <property name="uniqueResourceName"><value>XADBMS</value></property> 
      <property name="xaDataSourceClassName"> 
         <value>oracle.jdbc.xa.client.OracleXADataSource</value> 
      </property> 
      <property name="xaProperties"> 
        <props> 
            <prop key="user">xxx</prop> 
            <prop key="password">xxx</prop> 
            <prop key="URL">jdbc:oracle:thin:@147.151.240.xx:1521:orcl</prop> 
        </props> 
      </property>    
      <property name="poolSize" value="1"/> 
   </bean> 
	
	<bean id="jmsAccessor" class="com.test.spring.tx.xaatomikos.JmsAccessor">
		<property name="jmsTemplate" ref="jmsTemplate"/>
	    <property name="destination" ref="destination"/>
	</bean>
	<bean id="destination" class="org.apache.activemq.command.ActiveMQQueue">
		<constructor-arg index="0" value="example.yorker" />
	</bean>
	<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
	   <property name="connectionFactory" ref="atomikosConnectionFactory"/>
	   <property name="defaultDestination" ref="destination"/>
	   <property name="receiveTimeout" value="10000"/>
	   <property name="sessionTransacted" value="true" />
	</bean>
	
	<bean id="amqConnectionFactory" class="org.apache.activemq.ActiveMQXAConnectionFactory" >
        <property name="brokerURL" value="tcp://localhost:61616"/>
    </bean> 
    <bean id="atomikosConnectionFactory"
          class="com.atomikos.jms.AtomikosConnectionFactoryBean" init-method="init" destroy-method="close">
        <property name="uniqueResourceName" value="amq1"/>
        <property name="xaConnectionFactory" ref="amqConnectionFactory"/>
    </bean>
	<!--
    <bean id="jmsConnectionFactory"
        class="org.springframework.jms.connection.SingleConnectionFactory">
        <property name="targetConnectionFactory" ref="atomikosConnectionFactory" />
    </bean>
	-->	
	<bean id="atomikosTransactionManager"
          class="com.atomikos.icatch.jta.UserTransactionManager"
          init-method="init" destroy-method="close" >
        <property name="forceShutdown" value="false"/>
    </bean>
    <bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp" >
        <property name="transactionTimeout" value="300"/>
    </bean>
	<!--
	<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>
	-->
	 <bean id="jtaTransactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
        <property name="transactionManager" ref="atomikosTransactionManager"/>
        <property name="userTransaction" ref="atomikosUserTransaction"/>
    </bean> 
	<tx:advice id="txAdvice" transaction-manager="jtaTransactionManager">
		<tx:attributes>
			<tx:method name="*" propagation="REQUIRED"/>
		</tx:attributes>
	</tx:advice>
	<aop:config>
		<aop:pointcut id="serviceOperation"
			expression="execution(* com.test.spring.tx.xaatomikos.*Service*.*(..))" />
		<aop:advisor advice-ref="txAdvice" pointcut-ref="serviceOperation" />
	</aop:config>	
</beans>
2,Java操作数据库的代码Dao

public class DB1jdbcDAO {
	private JdbcTemplate jdbcTemplate;	
	public void setDataSource(DataSource dataSource) {
		this.jdbcTemplate = new JdbcTemplate(dataSource);
	}
	public void testInsert(int id, String val) {		
		this.jdbcTemplate.update("insert into A (ID, VAL) values (?, ?)", id, val);
	}
3,Java操作MQ的代码JMS accessor:

public class JmsAccessor {
	JmsTemplate jmsTemplate;
	Destination destination;
	public void send() {
		MessageCreator messageCreator = new MessageCreator() {
			public Message createMessage(Session session) {
				System.out.println("confactory type:" + jmsTemplate.getConnectionFactory().getClass().getName());
				TextMessage message = null;
				try {
					message = session.createTextMessage("Hello message");
				} catch (JMSException e) {
					e.printStackTrace();
				}
				return message;
			}
		};
		jmsTemplate.send(this.destination, messageCreator);
	}

	public void receive() {
		System.out.println("confactory type:" + jmsTemplate.getConnectionFactory().getClass().getName());
		TextMessage message = (TextMessage) jmsTemplate.receive();
		try {
			System.out.println("Message received:" + message.getText());
		} catch (JMSException e) {
			e.printStackTrace();
		}
	}
	public JmsTemplate getJmsTemplate() {
		return jmsTemplate;
	}
	public void setJmsTemplate(JmsTemplate jmsTemplate) {
		this.jmsTemplate = jmsTemplate;
	}
	public Destination getDestination() {
		return destination;
	}
	public void setDestination(Destination destination) {
		this.destination = destination;
	}
}
4客户访问端代码:

public class BuzSingleService {
	DB1jdbcDAO db1jdbcDAO;
	JmsAccessor jmsAccessor;
	public void testTX1() throws Exception {
		db1jdbcDAO.testInsert(0, "db1jdbcDAO val0");
		jmsAccessor.send();
........下面是main 方法中的代码
		ApplicationContext ctx = new ClassPathXmlApplicationContext("config/xaAtomikosAppcontext.xml");
		BuzSingleService serv =(BuzSingleService)ctx.getBean("buzSingleService");
		try {
			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.


原文链接:http://blog.csdn.net/kkdelta/article/details/7264752
加载中
返回顶部
顶部