Persistence unit as RESOURCE_LOCAL or JTA? - java

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.

Related

JTA transactions involving spring and non-spring

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.

Integration of hibernate transaction in jta transaction manager

In my standalone java application, jms and hibernate are used for fulfilling my requirements. I used the JTA transaction manager for the transaction management purposes. Can i enlist the XAResource for the hibernate and jms in the jta transaction to ensure the atomicity of my application.
Yes, it's possible. Called sometimes two-phase commit, it synchronises transactions between multiple resources.
First of all make sure you're RDBMS supports and has the feature turned on. In PostgreSQL, for example, this means setting the max_prepared_transactions configuration parameter from postgresql.conf to something above 0.
Also, make sure the JMS queue you're using support this transaction method. In Wildfly this means adding transaction="xa" on pooled-connection-factory.

Transaction Management outside Data Access Layer

Data Access Layer is not responsible for transaction management am I correct? I have these DAO implementations: HibernateDAO and SqlDAO. If I will choose Hibernate and handle its transaction management at above layer, when I switch to SQL then I will change every single transaction management made by the Hibernate to SQL? This is bad right? What strategy will I gonna use in this case? TIA.
I've never worked on transactions outside of spring and JTA. Spring offers a transactions across several different platforms using transactions. You may want to check that out.
Also, I've seen JTA transactions work on ejb, Hibernate and Jms messages, but not sure if it will work for jdbc and hibernate, more on hibernate transactions here.

Extended persistence context type with JPA 2 & Hibernate

I understand that an extended persistence context lasts the duration of the conversation or until the persistence context is closed by the container when the #Remove method of the stateful session bean completes (or the stateful session bean instance is otherwise destroyed).
Now obviously, the persistence context will also be closed in JPA 2/Hibernate when the bean is destroyed, but is there a corollary to #Remove in JPA 2/Hibernate?
Also, are there any pitfalls to keep in mind while using an extended persistence context?
JPA/Hibernate are persistence technologies. They do not handle session (entity manager) management. They provide the entity manager and let other technologies manage it.
manually - open and close entity managers
EJB3 - as you mentioned
CDI, spring, guice, etc. dependency injection frameworks.
PersistenceContextType.EXTENDED should be handled by the framework which injects the EntityManager where #PersistenceContext is present. This can't be JPA/Hibernate alone.

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!

Categories

Resources