Details
-
Type:
Bug
-
Status:
Open
-
Priority:
Major
-
Resolution: Unresolved
-
Affects Version/s: 3.1.2, 3.1.x, 3.2.1, 3.2.x
-
Fix Version/s: None
-
Component/s: Core: Transactions, Transport: JDBC
-
Environment:
Sun JDK 1.6.0_30
Windows XP SP3 32bit
-
User impact:Very High
-
Configuration:
-
Similar Issues:None
Description
As you should know, a common use case is the bridge pattern :
- read a message from an inbound endpoint (from a JMS queue or/and a database through JDBC).
- writing the message to an outbound endpoint (to a JMS queue or/and a database through JDBC).
<service name="myBridgeService"> <inbound> <jms:inbound-endpoint queue="/queue/inbox"/> </inbound> <outbound> <multicasting-router> <jms:outbound-endpoint queue="/queue/outbox" /> <jdbc:outbound-endpoint queryKey="insertMessageStmt" /> </multicasting-router> </outbound> </service>
What happens then if something goes wrong when writing the result to the outbound endpoint (eg. jdbc endpoint)? If you don't use XA Transaction on inbound and outbound endpoints, the message will not be rollbacked to the inbound endpoint in case of an Exception. So you will have to solve this issue by configuring <xa-transaction> on each endpoint with the appropriate transaction strategy.
<service name="myBridgeService"> <inbound> <jms:inbound-endpoint queue="/queue/inbox"> <xa-transaction action="ALWAYS_BEGIN" /> </jms:inbound-endpoint> </inbound> <outbound> <multicasting-router> <jms:outbound-endpoint queue="/queue/outbox"> <xa-transaction action="ALWAYS_JOIN" /> </jms:outbound-endpoint> <jdbc:outbound-endpoint queryKey="insertMessageStmt"> <xa-transaction action="ALWAYS_JOIN" /> </jdbc:outbound-endpoint> </multicasting-router> </outbound> </service>
But what happens now if you have a component between inbound and outbound enpoints ?
<service name="myDaoService"> <inbound> <jms:inbound-endpoint queue="/queue/inbox"> <xa-transaction action="ALWAYS_BEGIN" /> </jms:inbound-endpoint> </inbound> <component> <spring-object bean="messageDao" /> </component> <outbound> <multicasting-router> <jms:outbound-endpoint queue="/queue/outbox"> <xa-transaction action="ALWAYS_JOIN" /> </jms:outbound-endpoint> <jdbc:outbound-endpoint queryKey="insertMessageStmt"> <xa-transaction action="ALWAYS_JOIN" /> </jdbc:outbound-endpoint> </multicasting-router> </outbound> </service>
In most cases, the Spring object component (eg. messsageDao) will execute complicated business operations (from a currently existing business API) and also use a DataSource to execute several SQL select and update statements before returning a result to the outbound. These JDBC operations will be handled likely by Spring JdbcTemplate or even HibernateTemplate.
As far as I understand, Mule is fully responsible to handle enlistment/delistment and close of XA resources (see org.mule.transaction.XaTransaction). So by default, XA resources used by a Spring object component will not be handled by Mule and will not participate in the XA transaction started from Mule.
For completeness... I've also found a unit test for this usecase in Mule distribution under MULE_HOME/src/mule-3.1.2-src.zip/org/mule/test/integration/transaction/XATransactionsWithSpringDAO.java. When you execute this test, you will have a successful result but the XA resource used by the dao bean is not enlisted nor delisted in/from the transaction started from Mule.
Activity
| Field | Original Value | New Value |
|---|---|---|
| Attachment | JdbcConnectorDataSourceWrapper.java [ 14853 ] |
| Priority | To be reviewed [ 6 ] | Major [ 3 ] |
| Assignee | Pablo Kraan [ pablo.kraan ] |