原文链接:
http://www.javaworld.com/javaworld/jw-01-2009/jw-01-spring-transactions.html?page=4
Page 4 of 6
不是所有的供应商都提供这么简单的支持。做为可选方案,可以使用Apache ActiveMQ做为消息中间件并在消息代理中插入存储策略,这对几乎所有的数据库都可以正常工作。一旦你了解其中的窍门,配置起来还是蛮简单的。这在本文的shared-jms-db示范工程中有过说明。应用程序代码(在这里是单元测试代码)不需要知道具体使用的模式,因为它是通过Spring配置声明来启用的。
这个例子中的单元测试代码,SynchronousMessageTriggerAndRollbackTests
验证是否所有的功能在使用同步消息接收机制时都能正常工作。testReceiveMessageUpdateDatabase方法接收两个消息并且使用它们在数据库中插入两条数据。
当这个方法退出时,测试框架会回滚这个事务,这样你可以确认消息和数据库更新都被成功回滚,如列表3所示:
@AfterTransaction public void checkPostConditions() { assertEquals(0, SimpleJdbcTestUtils.countRowsInTable(jdbcTemplate, "T_FOOS")); List<String> list = getMessages(); assertEquals(2, list.size()); }
最重要的配置是ActiveMQ的持久化策略(persistence strategy),把消息系统连接到相同的业务数据源,并且Spring JmsTemplate上的标志用来接收消息。列表4展示了如何配置ActiveMQ持久化策略:
<bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory" depends-on="brokerService"> <property name="brokerURL" value="vm://localhost?async=false" /> </bean> <bean id="brokerService" class="org.apache.activemq.broker.BrokerService" init-method="start" destroy-method="stop"> ... <property name="persistenceAdapter"> <bean class="org.apache.activemq.store.jdbc.JDBCPersistenceAdapter"> <property name="dataSource"> <bean class="com.springsource.open.jms.JmsTransactionAwareDataSourceProxy"> <property name="targetDataSource" ref="dataSource"/> <property name="jmsTemplate" ref="jmsTemplate"/> </bean> </property> <property name="createTablesOnStartup" value="true" /> </bean> </property> </bean>
JmsTemplate
上的标志:
JmsTemplate
事务属性 <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate"> ... <!-- This is important... --> <property name="sessionTransacted" value="true" /> </bean>
sessionTransacted=true
,JMS会话事务API将永远不会被调用而且消息接收不能回滚。这里的重要因素是,带有特殊async=false参数的内嵌代理以及数据源的一个封装层,两者一起确保ActiveMQ使用和Spring相同的事务JDBC连接。一个共享数据库资源某些时候可以由已有的独立资源合成而来。特别是如果它们在相同的RDBMS平台里。企业级的数据库供应商都支持同义词(或当量)概念,这里一个数据模式(schema,Oracle的术语)中的表在另外的模式中被声明为同义词。通过这样的方式,该平台里被物理分割的数据可以被同一个JDBC客户端连接所操作。比如,一个基于ActiveMQ的共享资源模式在实际系统中的实现(和上面的示范不同)通常会包括为消息和业务数据创建同义词。
by iefreer