Spring Integration
Configuring Atomikos as the Spring JTA Transaction Manager
You basically have two big options: the basic case (with JTA property file lookup) or the advanced case (where everything is specified in the Spring configuration).
The Basic Case (Pre-3.3)
Atomikos can easily be configured as the Spring JTA transaction manager. The following code snippet shows how to specify this in your Spring configuration file:
<!-- Construct Atomikos UserTransactionManager, needed to configure Spring -->
<bean id="AtomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager"
init-method="init" destroy-method="close">
<!-- when close is called, should we force transactions to terminate or not? -->
<property name="forceShutdown" value="false" />
</bean>
<!-- Also use Atomikos UserTransactionImp, needed to configure Spring -->
<bean id="AtomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp">
<property name="transactionTimeout" value="300" />
</bean>
<!-- Configure the Spring framework to use JTA transactions from Atomikos -->
<bean id="JtaTransactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="transactionManager" ref="AtomikosTransactionManager" />
<property name="userTransaction" ref="AtomikosUserTransaction" />
</bean>
The Advanced Case (As of 3.3)
The advanced case adds the possibility to specify everything, including JTA properties and optional log administrators to manage the transaction logs.
<!-- Optional: add a log administrator -->
<bean id="localLogAdministrator" class="com.atomikos.icatch.admin.imp.LocalLogAdministrator"/>
<bean id="userTransactionService" class="com.atomikos.icatch.config.UserTransactionServiceImp" init-method="init" destroy-method="shutdownForce">
<constructor-arg>
<!-- IMPORTANT: specify all Atomikos properties here -->
<props>
<prop key="com.atomikos.icatch.service">com.atomikos.icatch.standalone.UserTransactionServiceFactory</prop>
</props>
</constructor-arg>
<property name="initialLogAdministrators">
<list>
<ref bean="localLogAdministrator"/>
</list>
</property>
</bean>
<!-- Construct Atomikos UserTransactionManager, needed to configure Spring -->
<bean id="AtomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager"
init-method="init" destroy-method="close" depends-on="userTransactionService">
<!-- when close is called, should we force transactions to terminate or not? -->
<property name="forceShutdown" value="false" />
</bean>
<!-- Also use Atomikos UserTransactionImp, needed to configure Spring -->
<bean id="AtomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp" depends-on="userTransactionService">
<property name="transactionTimeout" value="300" />
</bean>
<!-- Configure the Spring framework to use JTA transactions from Atomikos -->
<bean id="JtaTransactionManager" class="org.springframework.transaction.jta.JtaTransactionManager" depends-on="userTransactionService">
<property name="transactionManager" ref="AtomikosTransactionManager" />
<property name="userTransaction" ref="AtomikosUserTransaction" />
</bean>
Spring-Demarcated Transactions for POJOs
TODO: document - also explain the attributes for declarative transactions - see
http://www.atomikos-support.com/forums/viewtopic.php?p=2296
Receiving JMS Messages
You can receive messages either with the Atomikos receiver sessions, or with the Spring message listener containers.
With the Atomikos QueueReceiverSession(Pool)
See the examples in the Atomikos download for how to configure...
With Spring's MessageListenerContainer
You can also use Spring's message listener; the following XML fragment shows a complete example on how to configure this:
<bean id="xaFactory" class="org.apache.activemq.ActiveMQXAConnectionFactory">
<property name="brokerURL" value="tcp://localhost:61616" />
</bean>
<!-- Configure the JMS connector; call init to register for recovery! -->
<bean id="RealConnectionFactory" class="com.atomikos.jms.QueueConnectionFactoryBean" init-method="init">
<property name="resourceName" value="amq1" />
<property name="xaQueueConnectionFactory" ref="xaFactory" />
</bean>
<bean id="ConnectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory">
<property name="targetConnectionFactory" ref="RealConnectionFactory" />
</bean>
<!-- Construct Atomikos UserTransactionManager, needed to configure Spring -->
<bean id="AtomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager"
init-method="init" destroy-method="close">
<!-- when close is called, should we force transactions to terminate or not? -->
<property name="forceShutdown" value="false" />
</bean>
<!-- Also use Atomikos UserTransactionImp, needed to configure Spring -->
<bean id="AtomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp">
<property name="transactionTimeout" value="300" />
</bean>
<!-- Configure the Spring framework to use JTA transactions from Atomikos -->
<bean id="JtaTransactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="transactionManager" ref="AtomikosTransactionManager" />
<property name="userTransaction" ref="AtomikosUserTransaction" />
</bean>
<!-- a class that implements javax.jms.MessageListener -->
<bean id="MessageListener" class="jtatest.TextOutputMessageListener" />
<!-- a kind of message listener pool that will listen to messages posted to 'requestQueue'
with 3 threads, each one consuming a connection from bean 'ConnectionFactory' -->
<bean id="MessageListenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="transactionManager" ref="JtaTransactionManager" />
<property name="connectionFactory" ref="ConnectionFactory" />
<property name="messageListener" ref="MessageListener" />
<property name="destinationName" value="requestQueue" />
<property name="concurrentConsumers" value="1" />
<property name="receiveTimeout" value="3000" />
<property name="sessionTransacted" value="true"/>
</bean>
Note that the
sessionTransacted property of the listener container must be set to
true or it won't work!
Sending JMS Messages
For sending, again you have the option to use either the Atomikos classes or the Spring facilities...
With the Atomikos QueueSenderSession
See the examples in the Atomikos download for how to configure...
With Spring's JmsTemplate
The following XML snippet shows how to configure the Spring JmsTemplate to work with Atomikos.
<!-- The underying JMS vendor's XA connection factory. XA is required for transactional correctness. -->
<bean id="xaFactory" class="org.activemq.ActiveMQXAConnectionFactory">
<property name="brokerURL">
<value>tcp://localhost:61616</value>
</property>
</bean>
<!-- The Atomikos JTA-enabled TopicConnectionFactory, configured with the vendor's XA factory. -->
<bean id="topicConnectionFactoryBean" class="com.atomikos.jms.TopicConnectionFactoryBean" init-method="init">
<!-- The unique resource name needed for recovery by the Atomikos core. -->
<property name="resourceName">
<value>TOPIC_BROKER</value>
</property>
<property name="xaTopicConnectionFactory">
<ref bean="xaFactory"/>
</property>
</bean>
<!-- Where do we send updated time table info to? Note: this is a topic to allow multiple subscribers. -->
<bean id="topic" class="org.activemq.message.ActiveMQTopic">
<property name="physicalName">
<value>TIMETABLE_TOPIC</value>
</property>
</bean>
<!-- JMS template for easy sending of timetable update messages with Spring -->
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory">
<ref bean="topicConnectionFactoryBean"/>
</property>
<property name="defaultDestination">
<ref bean="topic"/>
</property>
<property name="receiveTimeout" value="1000"/>
<property name="sessionTransacted" value="true"/>
</bean>
Note that the
sessionTransacted attribute must be set to
true! For performance, you can also wrap the connection factory in Spring's
SingleConnectionFactory instead. This will reuse the same connection for sending in the JmsTemplate.
Accessing the Database
The database can be accessed in a variety of ways.
Configuring Atomikos DataSource
See the examples/demos included in the download for how to configure a data source in Spring.
Spring's JdbcTemplate
TODO
Spring's HibernateTemplate
The following XML fragment shows how to configure the HibernateTemplate for JTA transactions with Atomikos.
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="mappingResources">
<list>
<!-- list all your Hibernate mapping file locations here -->
<value>...</value>
...
</list>
</property>
<!-- IMPORTANT: make sure to refer to an ATOMIKOS JTA/XA datasource for the sessionFactory! -->
<property name="dataSource"><ref bean="datasource"/></property>
<!-- IMPORTANT: make sure to tell Hibernate to use JTA -->
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">...</prop>
<prop key="hibernate.connection.isolation">3</prop>
<prop key="hibernate.current_session_context_class">jta</prop>
<prop key="hibernate.transaction.factory_class">org.hibernate.transaction.JTATransactionFactory</prop>
<prop key="hibernate.transaction.manager_lookup_class">com.atomikos.icatch.jta.hibernate3.TransactionManagerLookup</prop>
</props>
</property>
</bean>
<!-- Configure the Hibernate template with the resulting sessionFactory -->
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory"><ref bean="sessionFactory"/></property>
</bean>
Spring JMS Performance
When using Spring's JMS support, it is highly recommended to always use the Spring
SingleConnectionFactory for the JMS template and the listener containers. Also, you should take care to set
sessionTransacted to
true for the JmsTemplate and the listener containers.
JMX Administration of Atomikos Transactions
From release 3.3 on, Atomikos can be configured for administration in JMX. The following shows
how this works with Spring and JDK 1.5 or higher.
<!-- Configure the Atomikos JMX transaction service to administer pending transactions -->
<bean id="jmxTransactionService" class="com.atomikos.icatch.admin.jmx.JmxTransactionService"/>
<!-- Spring JMX config -->
<bean id="mbeanServer" class="org.springframework.jmx.support.MBeanServerFactoryBean"/>
<!-- Export the Atomikos JMX transaction service to the local JMX service in the running VM (1.5 or higher) -->
<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter">
<property name="beans">
<map>
<entry key="atomikos:name=tx-service">
<ref bean="jmxTransactionService"/>
</entry>
</map>
</property>
<property name="server">
<ref bean="mbeanServer"/>
</property>
</bean>
--
GuyPardon - 26 Jul 2007