|
|
Article: Distributed Transactions in Spring, with and without XA
A new article has just been published on JavaWorld: Distributed Transactions in Spring, with and without XA. In the article, Dave Syer, guides you through seven patterns for distributed transactions in Spring applications, three of them with XA and four without. This article provides a follow-up to the already popular JavaWorld article from 2007: XA transactions using Spring.
This thread is provided to discuss the concepts and issues raised in the article and to comment and improve on the sample code supplied.
Adam FitzGerald
SpringSource
Nice article and nice to see that some kind of ChainedTransactionManager is going to be put into Spring 3.0.
One thing bothers me. What if I'm using ORM like Hibernate and have 2 databases. Many data errors happen when executing SQLs (INSERT/UPDATE/DELETE). Since in Hibernate most SQLs are executed at the end of transaction (during commit() on transaction manager) - situation when one db connection is commited and second rollbacked may happen much more often.
It can be avoided by flushing session after every operation but I doubt it is the way to go
What do you think ?
Thanks for the comments and the thought that went into them. Many good points raised, but I'll just respond directly to a couple for now.Originally Posted by rienceIt can be avoided by flushing session after every operation but I doubt it is the way to go
Good point about ORM being more complicated. Actually you don't have to flush after every operation - as long as the Best Efforts 1PC system (ChainedTransactionManager etc.) is aware of the sessions / persistence managers, all it has to do is flush them before any commits. It makes the implementation of the patterm more complicated, but it isn't in principle a problem.Originally Posted by GuyPardon-The Shared Tx Resource Pattern for JMS to JDBC: this works but ignores the sender-side of JMS (it is unrealistic to assume one huge shared DBMS for everything, especially for integration cases)?
True. But while it might not be trendy to use a shared DB, it is not uncommon - it's reliable and performs well if you have the cash to drop on the database vendor. I do concede that performance benefits might be use-case dependent, but that means that the pattern is still useful in many circumstances.
Also, I wouldn't want anyone to get the impression that the Shared Resource only works with a monolithic database. A distributed JMS (e.g. as many as one DB per node) is still an option, and you still want your message/db consumers to be atomic.
Same goes for the chatter between nodes in a distributed JMS really (the next comment above): as per usual your mileage may vary.
Originally Posted by rienceOne thing bothers me. What if I'm using ORM like Hibernate and have 2 databases. Many data errors happen when executing SQLs (INSERT/UPDATE/DELETE). Since in Hibernate most SQLs are executed at the end of transaction (during commit() on transaction manager) - situation when one db connection is commited and second rollbacked may happen much more often.
It can be avoided by flushing session after every operation but I doubt it is the way to go
What do you think ?
Actually, this is a known optimization (execution delayed till commit time), and a known trade-off. Need to disable it. E.g. Weblogic server had it as a standard deployment option, read more here: technology/pub...ocessing2.html
Overall, this Best Effort 1PC approach (we named it Multi-Transaction in Mule) has big implications for systems demanding higher performance. It's been reinvented for each system, and I'm happy that it is being made more accessible now (e.g. here's how a similar concept is configured in Mule: 6tolae ). Our implementation approach was slightly different - injecting a 'smart' transaction into existing TX-handling code.
Cheers,
Andrew
Dave Syer,
Why U Samples not working with stadalone application?
In, javaworld/j...ringxa-src.zip
I added only:
bean:
Code:
lt;?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?gt;
lt;beans xmlns=quot;schema/beansquot; xmlns:xsi=quot;2001/XMLSchema-instancequot; xmlns:context=quot;schema/contextquot; xsi:schemaLocation=quot;schema/beans schema/beans/spring-beans-2.5.xsd schema/context schema/context/spring-context-2.5.xsdquot;gt; lt;context:annotation-config/gt;
lt;bean id=quot;mmmquot;
class=quot;com..open.db.MultipleDatasourceTestsquot;gt;
lt;/beangt;
..................................Yours....
..................................
Class Main
Code:
package com..open.db;
import org..context.support.ClassPathXmlApplicationContext;
import exception.DDD;
public class Main {
public static void main(String[] args) {
MultipleDatasourceTests test = (MultipleDatasourceTests)
new ClassPathXmlApplicationContext(quot;/META-INF/spring/data-source-context.xmlquot;).getBean(
quot;mmmquot;);
try {
test.testInsertWithCheckForDuplicates();
} catch (Exception e) {
System.out.println(quot;n\n\n Test ROLBACK \n\n\nquot;);
e.printStackTrace();
}
}
}
Code:
@Transactional (propagation=Propagation.REQUIRED ,isolation=Isolation.DEFAULT, rollbackFor=Exception)
@Test
public void testInsertWithCheckForDuplicates() throws Exception { ............... ...............
thx! |
|