Vous êtes sur la page 1sur 23

XA transactions using Spring | JavaWorld

1 of 7

http://www.javaworld.com/article/2077714/java-web-development/xa-tr...

28-Oct-15 11:27 AM

XA transactions using Spring | JavaWorld

2 of 7

http://www.javaworld.com/article/2077714/java-web-development/xa-tr...

UserTransaction

javax.transaction.xa
XAResource, Xid and XAException

TransactionManager, Transaction, Status and Synchronization

28-Oct-15 11:27 AM

XA transactions using Spring | JavaWorld

3 of 7

http://www.javaworld.com/article/2077714/java-web-development/xa-tr...

PlatformTransactionManager

TransactionProxyFactoryBean
JtaTransactionManager
PlatformTransactionManager
HibernateTransactionManager
JdoTransactionManager

JmsTransactionManager

28-Oct-15 11:27 AM

XA transactions using Spring | JavaWorld

4 of 7

http://www.javaworld.com/article/2077714/java-web-development/xa-tr...

TransactionDefinition
TransactionAttribute

DefaultMessageListenerContainer
DefaultMessageListenerContainer
AbstractPollingMessageListenerContainer
MessageConsumer.receive()
JtaTransactionManager

28-Oct-15 11:27 AM

XA transactions using Spring | JavaWorld

5 of 7

http://www.javaworld.com/article/2077714/java-web-development/xa-tr...

XAConnectionFactory, XAConnection and XASession

mysql> use mydb1;


Database changed
mysql> select * from msgseq;
+---------+-----------+-------+
| APPNAME | APPKEY

| VALUE |

+---------+-----------+-------+
| spring

| execution |

13 |

+---------+-----------+-------+
1 row in set (0.00 sec)

28-Oct-15 11:27 AM

XA transactions using Spring | JavaWorld

6 of 7

http://www.javaworld.com/article/2077714/java-web-development/xa-tr...

mysql> use mydb2;


Database changed
mysql> select * from msgseq;
+---------+------------+-------+
| APPNAME | APPKEY

| VALUE |

+---------+------------+-------+
| spring

| aaaaa

| 15

| spring

| allocation | 13

+---------+------------+-------+
2 rows in set (0.00 sec)

<destinations>
<queue physicalName="test.q1" />
</destinations>

queue.test.q1=test.q1

EventHandler

28-Oct-15 11:27 AM

XA transactions using Spring | JavaWorld

7 of 7

http://www.javaworld.com/article/2077714/java-web-development/xa-tr...

public void handleEvent(boolean fail) throws Exception {


MessageSequenceDAO dao = (MessageSequenceDAO) springContext.getBean("sequenceDAO")
int value = 13;
String app = "spring";
String appKey = "execution";
int upCnt = dao.updateSequence(value, app, appKey);
log.debug(" sql updCnt->" + upCnt);
if (springContext.containsBean("sequenceDAO2")) {
// this is for use case 1 with JBossTS
MessageSequenceDAO dao2 = (MessageSequenceDAO) springContext.getBean("sequenceDAO
appKey = "allocation";
upCnt = dao2.updateSequence(value, app, appKey);
log.debug(" sql updCnt2->" + upCnt);
}
...
if (fail) {
throw new RuntimeException("Simulating Rollback by throwing Exception !!");
}
}

28-Oct-15 11:27 AM

XA transactions using Spring | JavaWorld

1 of 8

http://www.javaworld.com/article/2077714/java-web-development/xa-tr...

MessageSequenceDAO

if

28-Oct-15 11:28 AM

XA transactions using Spring | JavaWorld

2 of 8

http://www.javaworld.com/article/2077714/java-web-development/xa-tr...

<bean id="dsProps" class="java.util.Properties">


<constructor-arg>
<props>
<prop key="user">root</prop>
<prop key="password">murali</prop>
<prop key="DYNAMIC_CLASS">com.findonnet.service.transaction.jboss.jdbc.Mysql</p
</props>
</constructor-arg>
</bean>
<bean id="dataSource1" class="org.springframework.jdbc.datasource.DriverManagerDataSou
<property name="driverClassName">
<value>com.arjuna.ats.jdbc.TransactionalDriver</value>
</property>
<property name="url" value="jdbc:arjuna:mysql://127.0.0.1:3306/mydb1"/>
<property name="connectionProperties">
<ref bean="dsProps"/>
</property>
</bean>
<bean id="dataSource2" class="org.springframework.jdbc.datasource.DriverManagerDataSou
<property name="driverClassName">
<value>com.arjuna.ats.jdbc.TransactionalDriver</value>
</property>
<property name="url" value="jdbc:arjuna:mysql://127.0.0.1:3306/mydb2"/>
<property name="connectionProperties">
<ref bean="dsProps"/>
</property>
</bean>
<bean id="sequenceDAO" class="com.findonnet.persistence.MessageSequenceDAO">
<property name="dataSource">
<ref bean="dataSource1"/>
</property>
</bean>
<bean id="sequenceDAO2" class="com.findonnet.persistence.MessageSequenceDAO">
<property name="dataSource">
<ref bean="dataSource2"/>
</property>
</bean>

28-Oct-15 11:28 AM

XA transactions using Spring | JavaWorld

3 of 8

http://www.javaworld.com/article/2077714/java-web-development/xa-tr...

DynamicClass
com.findonnet.service.transaction.jboss.jdbc.Mysql
DynamicClass

DynamicClass
getDataSource()

shutdownDataSource()

getDataSource()

XADataSource
com.mysql.jdbc.jdbc2.optional.MysqlXADataSource.
DriverManagerDataSource

handleEvent()
EventHandler

<bean id="eventHandlerTarget" class="com.findonnet.messaging.EventHandler"></bean>


<bean id="eventHandler" class="org.springframework.transaction.interceptor.Transaction
<property name="transactionManager"><ref bean="transactionManager" /></property>
<property name="target"><ref bean="eventHandlerTarget"/></property>
<property name="transactionAttributes">
<props>
<prop key="handle*">PROPAGATION_REQUIRED,-Exception</prop>
</props>
</property>
</bean>

TransactionProxyFactoryBean
"PROPAGATION_REQUIRED,-Exception"

"PROPAGATION_REQUIRED,-Exception"
EventHandler
Exception

JtaTransactionManager
eventHandler
JtaTransactionManager

28-Oct-15 11:28 AM

XA transactions using Spring | JavaWorld

4 of 8

http://www.javaworld.com/article/2077714/java-web-development/xa-tr...

<bean id="jbossTransactionManager"
class="com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionManagerImple">
</bean>
<bean id="jbossUserTransaction"
class="com.arjuna.ats.internal.jta.transaction.arjunacore.UserTransactionImple"/>
<bean id="transactionManager"

class="org.springframework.transaction.jta.JtaTransacti

<property name="transactionManager">
<ref bean="jbossTransactionManager" />
</property>
<property name="userTransaction">
<ref bean="jbossUserTransaction" />
</property>
</bean>

JtaTransactionManager
com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionManagerImple
com.arjuna.ats.internal.jta.transaction.arjunacore.UserTransactionImple

28-Oct-15 11:28 AM

XA transactions using Spring | JavaWorld

5 of 8

http://www.javaworld.com/article/2077714/java-web-development/xa-tr...

EventHandler

public void handleEvent(boolean fail) throws Exception {


MessageSequenceDAO dao = (MessageSequenceDAO) springContext.getBean("sequenceDAO")
int value = 13;
String app = "spring";
String appKey = "execution";
int upCnt = dao.updateSequence(value, app, appKey);
log.debug(" sql updCnt->" + upCnt);
...
if (springContext.containsBean("appSenderTemplate")) {
this.setJmsTemplate((JmsTemplate) springContext.getBean("appSenderTemplate"));
this.getJmsTemplate().convertAndSend("Testing 123456");
log.debug("Sent message succesfully");
}
if (fail) {
throw new RuntimeException("Simulating Rollback by throwing Exception !!");
}
}

JmsTemplate

MainApp

handleEvent

if

28-Oct-15 11:28 AM

XA transactions using Spring | JavaWorld

6 of 8

http://www.javaworld.com/article/2077714/java-web-development/xa-tr...

<bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">


<property name="environment">
<props>
<prop key="java.naming.factory.initial">
org.apache.activemq.jndi.ActiveMQInitialContextFactory
</prop>
</props>
</property>
</bean>
<bean id="appJmsDestination"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiTemplate">
<ref bean="jndiTemplate"/>
</property>
<property name="jndiName" value="test.q1"/>
</bean>
<bean id="appSenderTemplate"
class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory">
<ref bean="queueConnectionFactoryBean"/>
</property>
<property name="defaultDestination">
<ref bean="appJmsDestination"/>
</property>
<property name="messageTimestampEnabled" value="false"/>
<property name="messageIdEnabled" value="false"/>
<!-- sessionTransacted should be true only for Atomikos -->
<property name="sessionTransacted" value="true"/>
</bean>

JndiTemplate
appJmsDestination

appJmsDestination

appSenderTemplate
appSenderTemplate

queueConnectionFactoryBean

sessionTransacted

prepare()

28-Oct-15 11:28 AM

XA transactions using Spring | JavaWorld

7 of 8

http://www.javaworld.com/article/2077714/java-web-development/xa-tr...

<bean id="xaFactory" class="org.apache.activemq.ActiveMQXAConnectionFactory">


<constructor-arg>
<value>tcp://localhost:61616</value>
</constructor-arg>
</bean>
<bean id="queueConnectionFactoryBean"
class="com.atomikos.jms.QueueConnectionFactoryBean" init-method="init">
<property name="resourceName">
<value>Execution_Q</value>
</property>
<property name="xaQueueConnectionFactory">
<ref bean="xaFactory" />
</property>
</bean>
<bean id="atomikosTransactionManager"
class="com.atomikos.icatch.jta.UserTransactionManager" init-method="init" destroy-met
<property name="forceShutdown"><value>true</value></property>
</bean>
<bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp"/
<bean id="transactionManager"
class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="transactionManager">
<ref bean="atomikosTransactionManager" />
</property>
<property name="userTransaction">
<ref bean="atomikosUserTransaction" />
</property>
</bean>

xaFactory
org.apache.activemq.ActiveMQXAConnectionFactory

28-Oct-15 11:28 AM

XA transactions using Spring | JavaWorld

8 of 8

http://www.javaworld.com/article/2077714/java-web-development/xa-tr...

<bean id="dataSource" class="com.atomikos.jdbc.SimpleDataSourceBean" init-method="init"


<property name="uniqueResourceName"><value>Mysql</value></property>
<property name="xaDataSourceClassName">
<value>com.mysql.jdbc.jdbc2.optional.MysqlXADataSource</value>
</property>
<property name="xaDataSourceProperties">
<value>URL=jdbc:mysql://127.0.0.1:3306/mydb1?user=root&password=murali</value>
</property>
<property name="exclusiveConnectionMode"><value>true</value></property>
</bean>

28-Oct-15 11:28 AM

XA transactions using Spring | JavaWorld

1 of 8

http://www.javaworld.com/article/2077714/java-web-development/xa-tr...

com.mysql.jdbc.jdbc2.optional.MysqlXADataSource

28-Oct-15 11:28 AM

XA transactions using Spring | JavaWorld

2 of 8

http://www.javaworld.com/article/2077714/java-web-development/xa-tr...

<bean id="ConnectionFactory" factory-bean="ConnectionFactoryBean" factory-method="creat


<bean id="dataSourceBean1" class="bitronix.tm.resource.jdbc.DataSourceBean">
<property name="className" value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource" />
<property name="uniqueName" value="mysql" />
<property name="poolSize" value="2" />
<property name="driverProperties">
<props>
<prop key="user">root</prop>
<prop key="password">murali</prop>
<prop key="databaseName">mydb1</prop>
</props>
</property>
</bean>
<bean id="Db1DataSource" factory-bean="dataSourceBean1" factory-method="createResource
<bean id="BitronixTransactionManager" factory-method="getTransactionManager"
class="bitronix.tm.TransactionManagerServices" depends-on="btmConfig,ConnectionFac
<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactio
<property name="transactionManager" ref="BitronixTransactionManager" />
<property name="userTransaction" ref="BitronixTransactionManager" />
</bean>
<bean id="btmConfig" factory-method="getConfiguration" class="bitronix.tm.TransactionM
<property name="serverId" value="spring-btm-sender" />
</bean>

JmsTemplate

BitonixTransactionManager

28-Oct-15 11:28 AM

XA transactions using Spring | JavaWorld

3 of 8

http://www.javaworld.com/article/2077714/java-web-development/xa-tr...

MessageHandler

28-Oct-15 11:28 AM

XA transactions using Spring | JavaWorld

4 of 8

http://www.javaworld.com/article/2077714/java-web-development/xa-tr...

public void handleOrder(String msg) {


log.debug("Receieved message->: " + msg);
MessageSequenceDAO dao = (MessageSequenceDAO) MainApp.springCtx.getBean("sequenceDAO"
String app = "spring";
String appKey = "allocation";
int upCnt = dao.updateSequence(value++, app, appKey);
log.debug("Update SUCCESS!! Val: " + value + " updateCnt->"+ upCnt);
if (fail)
throw new RuntimeException("Rollback TESTING!!");
}

MessageHandler
handleOrder()
MessageListenerAdapter

<bean id="msgHandler" class="com.findonnet.messaging.MessageHandler"/>


<bean id="msgListener" class="org.springframework.jms.listener.adapter.MessageListe
<property name="delegate" ref="msgHandler"/>
<property name="defaultListenerMethod" value="handleOrder"/>
</bean>

28-Oct-15 11:28 AM

XA transactions using Spring | JavaWorld

5 of 8

http://www.javaworld.com/article/2077714/java-web-development/xa-tr...

<bean id="listenerContainer" class="org.springframework.jms.listener.DefaultMessageList


destroy-method="close">
<property name="concurrentConsumers" value="1"/>
<property name="connectionFactory" ref="queueConnectionFactoryBean" />
<property name="destination" ref="appJmsDestination"/>
<property name="messageListener" ref="msgListener"/>
<property name="transactionManager" ref="transactionManager"/>
<property name="sessionTransacted" value="false"/>
<property name="receiveTimeout" value="5000"/>
<property name="recoveryInterval" value="6000"/>
<property name="autoStartup" value="false"/>
</bean>

DefaultMessageListenerContainer

28-Oct-15 11:28 AM

XA transactions using Spring | JavaWorld

6 of 8

http://www.javaworld.com/article/2077714/java-web-development/xa-tr...

pointcut xaCalls() : call(*

XAResource.*(..))

|| call(*

TransactionManager.*(..))

|| call(*

UserTransaction.*(..))

;
Object around() : xaCalls() {
log.debug("XA CALL -> This: " + thisJoinPoint.getThis());
log.debug("

-> Target: " + thisJoinPoint.getTarget());

log.debug("

-> Signature: " + thisJoinPoint.getSignature());

Object[] args = thisJoinPoint.getArgs();


StringBuffer str = new StringBuffer(" ");
for(int i=0; i< args.length; i++) {
str.append(" [" + i + "] = " + args[i]);
}
log.debug(str);
Object obj = proceed();
log.debug("XA CALL RETURNS-> " + obj);
return obj;
}

suspend()

resume()

28-Oct-15 11:28 AM

XA transactions using Spring | JavaWorld

7 of 8

JmsTemplate

http://www.javaworld.com/article/2077714/java-web-development/xa-tr...

DefualtMessageListenerContainer

JmsTemplate
DefaultMessageListenerContainer

SingleConnnectionFactory

28-Oct-15 11:28 AM

XA transactions using Spring | JavaWorld

8 of 8

http://www.javaworld.com/article/2077714/java-web-development/xa-tr...

28-Oct-15 11:28 AM