Original article:
Http://www.javaworld.com/javaworld/jw-01-2009/jw-01-spring-transactions.html? Page = 4
Page 4 of 6
Not all vendors provide such simple support. As an optional solution, you can use Apache activemq as the message-oriented middleware and insert a storage policy into the message proxy, which works normally for almost all databases. Once you understand the tips, the configuration is quite simple. This is described in the shared-JMS-DB demonstration project in this article. Application code (unit test code here) does not need to know the specific mode of use, because it is enabled through spring configuration declaration.
The unit test code in this example, synchronousmessagetriggerandrollbacktests
Verify that all functions work properly when synchronous message receiving is used.The testreceivemessageupdatedatabase method receives two messages and uses them to insert two data entries into the database.
When the method exits, the test framework rolls back the transaction, so that you can confirm that the message and database update are successfully rolled back, as shown in list 3:
List 3. Confirm the rollback of messages and database updates
@AfterTransactionpublic void checkPostConditions() { assertEquals(0, SimpleJdbcTestUtils.countRowsInTable(jdbcTemplate, "T_FOOS")); List<String> list = getMessages(); assertEquals(2, list.size());}
The most important configuration is the persistence strategy of activemq, which connects the message system to the same business data source and uses the flag on Spring jmstemplate to receive messages. List 4 shows how to configure the activemq persistence policy:
List 4. activemq persistence Configuration
<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>
List 5 shows the spring
JmsTemplate
Flag on: List 5. Set
JmsTemplate
Transaction attributes
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate"> ... <!-- This is important... --> <property name="sessionTransacted" value="true" /></bean>
NosessionTransacted=true
, The JMS session transaction API will never be called and the message receiving cannot be rolled back. The important factor here is that the embedded proxy with the special async = false parameter and an encapsulation layer of the data source ensure that activemq uses the same transaction JDBC connection as spring. A shared database resource can sometimes be merged from an existing independent resource. Especially if they are on the same RDBMS platform. Enterprise-level database vendors support the concept of synonyms (or equivalent). tables in a schema (Oracle term) are declared as synonyms in another schema. In this way, the physically split data in the platform can be connected to the same JDBC client. For example, the implementation of an activemq-based shared resource mode in the actual system (different from the above Demonstration) usually includes creating synonyms for messages and business data.
By iefreer