JTA transactions involving spring and non-spring - java

By using an external jta manager like atomikos or bitronix, is it possible to combine a spring transaction and a non-spring transaction? If possible, do I still need to annotate the method as transactional - what if the transactions span across methods or classes?

Then you should allow the other library use the same JTA library which you configured in Spring with either Bitronix or Atomikos.
This way, you have a a JTA transcation manager configured in Spring and a single JTA DataSource which you need to pass to the outer library via the hibernate.connection.datasource configuration property.

Related

Difference between Spring JtaTransactionManager and HibernateTransactionManager

What is the difference between Spring JtaTransactionManager and HibernateTransactionManager and when to use one in my application? I know about HibernateTransactionManager and I can use it if I use Hibernate as my ORM tool but I didn't understand when to use JtaTransactionManager.
HibernateTransactionManager is used to manage transactions on top of a single Hibernate SessionFactory. If your application uses only a JDBC-compliant database to store data (that is, no ERP, JMS queue, file system, etc. is involved) that you access using Hibernate, you can use a HibernateTransactionManager in your application.
If however you have business operations that can modify multiple data stores at the same time and you need to ensure data consistency across all the stores, you will need to use JTA transactions. JTA support is provided either by JavaEE containers like JBoss, WebLogic or WebSphere or third-party JTA providers like Atomikos or Bitronix. JtaTransactionManager enables you to integrate a JTA provider with your Spring application. JtaTransactionManager only facilitates integration of a JTA transaction provider and is not a provider in itself. The underlying data sources that you want to participate in transactions should also support JTA transactions, which is usually implemented in the driver layer. For example, most JDBC drivers have a JTA and a non-JTA implementation.

Spring standalone JMS+JDBC single transaction

Currently I have a spring JMS listener which listens on to an EMS topic and on getting a message processes it and persists it. However, I would like to do all this under one transaction. I am aware this requires XA since there are two global resources which have to register with the Transaction Manager. This can be achieved via JTA that spring provides. However, since my application is standalone, do I require to include a third party JTA standalone implementation like Bitronix or JOTM. I ask this because since both are spring resources, the default JTA should handle this.
Yes you will need to include a third-party TransactionManager implementation that supports XA.
Most application servers e.g. JBoss will bundle an XA TransactionManager of their choice. This is one of the reasons to choose an ApplicationServer over something like Tomcat or a standalone application; the configuration of things like XA transactions is basically done for you.
Sometimes an ApplicationServer is too heavyweight (although I think this is becoming less of a problem) or you can't use one. In this scenario it is your responsibility to provide the TransactionManager implementation if you want to use XA.
You can take your pick from implementations such as: JBossTS, Atomikos Transaction Essentials or Bitronix JTA.
Spring does include a JTATransactionManager implementation. This will either use pre-configured locations to detect the selected XA implementation if you're running in an ApplicationServer, or alternatively you need to configure it yourself if you're in a standalone environment.
There are some excellent resources on configuring an XA TransactionManager with Spring:
http://spring.io/blog/2011/08/15/configuring-spring-and-jta-without-full-java-ee/
http://www.javaworld.com/article/2077714/java-web-development/xa-transactions-using-spring.html

How can I use the same transaction in Spring and an EJB?

I have no development experience with Spring, since we're a Java EE shop. However, we are looking into a solution for our needs that runs on Spring and should integrate our existing Java EE solution.
After reading the Spring 3.0.5 documentation, I'm still uncertain how a transaction can be propagated from Spring to an EJB.
For instance, a Spring bean would create a transaction, save some stuff into one database and then hand over the transaction to one of our stateless session beans, which (using JPA) saves some other stuff into another database. And all of this must run under the same transaction, which is committed when the control is returned to the Spring bean.
Also, I'm not clear about the deployment: Would Spring run as a webapp in the EAR that contains the session beans?
if you configure Spring to use a JTATransactionManager and then call your SessionBean from within Spring the bean should actually pick up the Spring-created transaction. Have look here: http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/htmlsingle/spring-framework-reference.html#transaction-application-server-integration and the described <tx:jta-transaction-manager/>
I actually only did it the other way around (joining EJB Transaction in spring) so I'm not completely sure, but you can easily test it by setting
#TransactionAttribute(TransactionAttributeType.MANDATORY)
on your SessionBean and call it from spring... if there's not existing Transaction you will end up with a TransactionRequiredException

How to use JTA support in Tomcat 6 for Hibernate?

They recommend using JTA transaction support in Java EE environment.
But how to configure JTA in Tomcat6 so that Hibernate Session could use it ?
Starting with version 3.0.1, Hibernate added the SessionFactory.getCurrentSession() method. Initially, this assumed usage of JTA transactions, where the JTA transaction defined both the scope and context of a current session. Given the maturity of the numerous stand-alone JTA TransactionManager implementations, most, if not all, applications should be using JTA transaction management, whether or not they are deployed into a J2EE container. Based on that, the JTA-based contextual sessions are all you need to use.
(Hibernate Reference Documentation | Architecture. Contextual Sessions)
If you want JTA support in Tomcat you'll need to use a standalone transaction manager like Atomikos, JOTM, Bitronix, SimpleJTA, JBossTS or GeronimoTM/Jencks. But honestly, if you're not going to handle transactions across multiple resources, then you can live without JTA (and if you really need JTA, use a full blown application server).
If you just want to use SessionFactory.getCurrentSession() you can just add the following two lines to your hibernate.cfg.xml:
<property name="transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</property>
<property name="hibernate.current_session_context_class">thread</property>
This will give you a unique Session for each thread. As a servlet request is always handled within one thread (given that your code doesn't spawn new ones), the Session will live for the whole request.
Don't forget to use a filter to close the Session after the request!

Persistence unit as RESOURCE_LOCAL or JTA?

I have queries as below:
What is the difference of these two?
Are both of these supported by all databases?
Are JPA TransactionManager and JTA TransactionManager different?
JPA implementations have the choice of managing transactions themselves (RESOURCE_LOCAL), or having them managed by the application server's JTA implementation.
In most cases, RESOURCE_LOCAL is fine. This would use basic JDBC-level transactions. The downside is that the transaction is local to the JPA persistence unit, so if you want a transaction that spans multiple persistence units (or other databases), then RESOURCE_LOCAL may not be good enough.
JTA is also used for managing transactions across systems like JMS and JCA, but that's fairly exotic usage for most of us.
To use JTA, you need support for it in your application server, and also support from the JDBC driver.
As an addition to other answers
Here is an excerpt from the extremely useful article (published on the Apache TomEE website), which can also help answer the OP's first question (the link to the article is below).
Comparing RESOURCE_LOCAL and JTA persistence
contexts
With <persistence-unit
transaction-type="RESOURCE_LOCAL">
YOU are responsible for EntityManager
(PersistenceContext/Cache) creating and tracking...
You must use the
EntityManagerFactory to get an EntityManager
The resulting EntityManager instance
is a PersistenceContext/Cache An
EntityManagerFactory can be injected via the
#PersistenceUnit annotation only (not
#PersistenceContext) You are not allowed to
use #PersistenceContext to refer to a unit of type RESOURCE_LOCAL
You must use the
EntityTransaction API to begin/commit around
every call to your EntityManger Calling
entityManagerFactory.createEntityManager() twice results in
two separate EntityManager instances and therefor
two separate PersistenceContexts/Caches. It
is almost never a good idea to have more than one
instance of an EntityManager in use (don't create a
second one unless you've destroyed the first)
With <persistence-unit
transaction-type="JTA"> the
CONTAINER will do EntityManager
(PersistenceContext/Cache) creating and tracking...
You cannot use the
EntityManagerFactory to get an EntityManager
You can only get an EntityManager supplied by the
container An EntityManager
can be injected via the #PersistenceContext
annotation only (not #PersistenceUnit) You are
not allowed to use #PersistenceUnit to refer to a
unit of type JTA The EntityManager given by
the container is a reference to the
PersistenceContext/Cache associated with a JTA Transaction.
If no JTA transaction is in progress, the EntityManager
cannot be used because there is no
PersistenceContext/Cache. Everyone with an EntityManager
reference to the same unit in the same
transaction will automatically have a reference to the
same PersistenceContext/Cache The
PersistenceContext/Cache is flushed and cleared at
JTA commit time
Anyone interested in learning the Java Persistence API - please do yourself a favor and read the full article here: JPA Concepts: JPA 101.
Resource_Local and JTA are transaction managers (methods of doing transactions). This is not the property of database but the component responsible for coordinating transactions. JPA and JTA transaction managers are different. JPA transaction manager is responsible for JPA transactions and you want to use one if you are only doing JPA transaction. JTA transaction manager is general purpose transaction manager and can enlist other resources such as JMS queues in transaction. Typically Java EE containers employ a JTA transaction manager for EJBs, JPA entities, etc.
resource_local vs JTA its about local transaction vs global transaction. It's about can we manage multiple resources under a single transaction.
CMT vs BMT its about who is opening and closing transaction - application developer or application server.

Categories

Resources