I'd like to write my next tiny Java webapp by using one of micro-frameworks. E.g. Spark or Jooby. The problem is that both of them doesn't support JTA, so I need to use one of third-party libraries. I've googled for open-source JTA implementations and found two: Atomikos and Bitronix. It seems that the latter project is slightly abandoned so I've decided to go with Atomikos. Unfortunately documentation is scarce so I can't find answers to my questions.
Here is the use case. Suppose we have two DAO classes which methods should be executed under single transaction:
class SomeService {
// both injected by Guice
private FooDao fooDao;
private BarDao barDao;
public void someMethod() {
// both methods should be executed in a single transaction
fooDao.insert(new Foo());
barDao.insert(new Bar());
}
}
I've never used javax.transaction
API directly/manually before (you know declarative transactions are very simple with Spring) so I'm a bit confused. JTA provides two general abstractions(UserTransaction
and TransactionManager
) and they both have methods to handle JDBC transaction. As far as I understand TransactionManager operates UserTransaction objects by using ThreadLocal variables. Therefore UserTransaction should be thread-confined and TransactionManager supposed to be thread-safe. Am I correct?
So there are several approaches possible:
- I can inject TransactionManager into my service (via Guice) and use it directly.
- I can share TransactionManager via public static variable.
- I can create an UserTransaction provider/factory (via Guice) and get objects from it.
Which is correct/best-practice?
Another question if someone familiar with Atomikos is that it provides two transaction manager implementations (maybe even more): J2eeTransactionManager and UserTransactionManager. Again documentation is too scarce so I don't see any difference except JNDI. I suppose UserTransactionManager should be enough for my purposes but description states the following
J2eeTransactionManager
An implementation of TransactionManager that should be used by J2EE applications.
.. without any explanation.
ps. Sorry my english isn't well I know it.
Ок, since no-one answered me, after digging into source code, I think I'm ready to answer my own question:
So it is safe to have one TM-per-webapp instance, which you can share any way you like. Since Atomikos TM supposed to be instantiated it's better to share it through dependency injection. Bitronix TM can be used through public static method as any other singleton.
Additionally you can manage transactions via JNDI. You can find an example in the Java Persistence with Hibernate book source code.