Edit: Mule 3.4.1
We have a Mule flow that alternates reads from one database with inserts to another, all wrapped inside a transactional scope. In this particular case, one of the later insertions fails and we expect everything to roll back.
When we look in the logs, we see an exception (e.g., duplicate PRIMARY KEY) for the second insertion (i.e., BulkInsertInstanceToCache in the example below). When we look in the database, we see the data from the first insert (BulkInsertActivityToCache in the example below). We expected all data to be gone.
Are we configuring this scope incorrectly for the behavior we want?
Here's a sample of the code where I've cut it down to just two insertions to show the type of processing being done.
<flow name="ProcessBulkUpdateCache" processingStrategy="synchronous" doc:name="ProcessBulkUpdateCache">
<transactional action="ALWAYS_BEGIN" doc:name="Transactional">
<jdbc-ee:outbound-endpoint exchange-pattern="request-response"
queryKey="GetActivitiesForCache" queryTimeout="-1" connector-ref="SumTotalDatabase">
<jdbc-ee:transaction action="NONE" />
</jdbc-ee:outbound-endpoint>
<jdbc-ee:outbound-endpoint exchange-pattern="request-response"
queryKey="BulkInsertActivityToCache" queryTimeout="-1" connector-ref="EAIServiceDatabase">
</jdbc-ee:outbound-endpoint>
<jdbc-ee:outbound-endpoint exchange-pattern="request-response"
queryKey="GetInstancesForCache" queryTimeout="-1" connector-ref="SumTotalDatabase">
<jdbc-ee:transaction action="NONE" />
</jdbc-ee:outbound-endpoint>
<jdbc-ee:outbound-endpoint exchange-pattern="request-response"
queryKey="BulkInsertInstanceToCache" queryTimeout="-1" connector-ref="EAIServiceDatabase">
</jdbc-ee:outbound-endpoint>
</transactional>
<catch-exception-strategy doc:name="Unexpected">
...etc.
</catch-exception-strategy>
</flow>
Edit I tried adding a BEGIN_OR_JOIN transaction element in the first INSERT and an ALWAYS_JOIN transaction element in the second but the code then throws an exception when it reaches the second that there is no transaction open to join.
Using ALWAYS_BEGIN
and ALWAYS_JOIN
respectively is the way to go.
But, if it's two different DBs, you need to use XA transactions. A local transaction can't enrol resources from two different databases.