本文简单介绍一下在Spring通过声明管理一个有数据库和ActiveMQ参入的全局事务,事务管理器的实现为Atomikos.全局事务的步骤为
1,更新数据库操作.
2访问ActiveMQ资源.
3,提交在数据库A中的操作.
4,提交在ActiveMQ中的操作.
上面的所有步骤应该保证要么全部成功,要么全部回滚.下面是实现的步骤:
1,配置Spring文件:
2,Java操作数据库的代码Dao
3,Java操作MQ的代码JMS accessor:
4客户访问端代码:
*一个问题是,在数据库操作和MQ操作都完成后,程序没有退出,不断有如下log输出:
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>
- 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);
- }
- 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;
- }
- }
- 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();
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.