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
Related
From what I have read so far, Propagation.REQUIRES_NEW makes use of transaction suspension capabilities in most common Java EE containers (JBoss, Glassfish, etc.)
However, as we're running Spring Data inside Vert.x, which is container-less, I'd like to find a definitive answer as to whether REQUIRES_NEW is supported in this scenario, or if we will have to use another approach for this.
You can use Spring #Transactional annotations out of a JavaEE container. It will work well if you only use a database.
If you mix transactional components (a relational database and a message broker) then you need a transaction manager, which is often only available in JavaEE container.
I'm not a Spring or SpringBoot expert but I am pretty sure it's not difficult nowadays to add a transaction manager to a Spring/Tomcat project.
As for running Spring Data in Vert.x, it will work fine if you deploy this code in worker verticles. Check out the spring-worker sample in the vertx-examples repository on GitHub
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.
I have some confusion on using JTA within the Spring Framework on Apache Tomcat and i hope someone will clarify as after many research i can't seem to find the correct answer as of yet.
I am developing a web application using Spring Framework to be running on Apache Tomcat 6.
I read somewhere that Spring's does support for JTA but it delegates to the underlying JavaEE application server. Now this is where i am confused because i Tomcat is not a full JavaEE application server - it is merely a servlet container and as i believe it doesn't provide JTA implementation like the full JavaEE application server (Glassfish/Wildfly etc...) does.
But when i do something like the following the transaction aspect of it works:
#Transactional
public class ServiceClassImpl implements ServiceInterface {
// code here that involves transactions e.g. calling DAO code
...
}
So, i'm confused. I hope someone will enlighten me.
The answer is: NO.
Tomcat 6.x (7&8) don't provide JTA out-of-the-box because they don't have a transaction manager which is required as a separate component to monitor multiple resources (e.g. datasources).
The mentioned answer How to use JTA support in Tomcat 6 for Hibernate? already gives a list of additional JTA transaction managers that can be used alongside Tomcat.
Spring supports declarative transaction management via a platform transaction manager (TM) and provides some implementations (e.g. datasources) that make #Transactional work on a single resource without the additional TM.
Understanding the Spring Framework transaction abstraction provides more details and Spring Boot can be easily configured to run Atomikos or Bitronix Transaction managers on the embedded Tomcat.
JTA provides you with distributed transactions support, but if JTA is not available like in Tomcat, you still can use local JDBC transactions.
YES :-)
JTA can be used in Tomcat, for instance via https://www.atomikos.com
The trick is to use a componentized JTA implementation.
Cheers
I have a situation to integrate two independent systems. One is using J2EE,EJBs and other is Spring based. Now the problem is both the systems can call methods of each other and i want to manage transactions as well. I am not sure how to coordinate both applications transaction managers as both are using different one (Spring and EJB).
Any one has an idea how to do this ?
First of all, both applications should use Extended transactions (XA transactions) on DataSource level (and for other resources such as Message Queues, JCA adapters or whatever resources you use in application).
Method calls should be done through Remote EJB call or web services that use WS-AtomicTransaction to handle transaction boundaries. If you do not want to change your architecture to add Remote EJBs, your best bet is to use web services with WS-AT that use XA transactions under the hood.
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!