I'm developing a web application based on JPA + Hibernate, Spring and Wicket. I was wondering what's the best way of implementing transactions in my code? What transaction manager should I use? Should it be org.springframework.orm.jpa.JpaTransactionManager, or org.springframework.jdbc.datasource.DataSourceTransactionManager or something else? I'd like to use Spring for managing my transactions.
nanda is right, you can only use JpaTransactionManager. The Transaction Manager abstraction we are talking about here is Spring's PlatformTransactionManager interface, and JPATransactionManager is the only implementation of that interface that understands JPA.
You should read the chapter Transaction Management from the Spring reference to better understand this topic.
The org.springframework.transaction.PlatformTransactionManager interface is the key abstraction in the Spring API providing essential methods for controlling transaction operations at run-time: begin, commit and rollback.
PlatformTransactionManager interface, its implementations
JtaTransactionManager -----> JTA
DataSourceTransactionManager -----> JDBC
JpaTransactionManager ------> JPA
HibernateTransactionManager ------> Hibernate
it depand on your requirment which moudle of spring your are using
org.springframework.orm.jpa.JpaTransactionManager
My preference is to use this with annotation:
<tx:annotation-driven transaction-manager="myTxManager" />
Related
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.
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.
If JTA is an API, can I use Hibernate as an implementation of JTA?
I have an application with Spring and Hibernate and I wonder which framework should be responsible for transactions, Spring or Hibernate?
Hibernate is not an implementation of JTA. Hibernate is a JPA implementation.
JTA is an enterprise transaction spec, that's implemented by Java EE providers or stand-along transaction managers (e.g. Bitronix).
Hibernate offers a Transaction API abstraction because ORM tools employ a transactional write-behind Persistence Context.
Spring offers a transaction management abstraction, which allows you to switch from RESOURCE_LOCAL to JTA transactions with just some trivial configuration changes.
Spring manages to integrate on top of Hibernate/JPA Transaction API abstraction too.
If you use Spring, then you should take advantage of its transaction management abstraction, and so you don't have to use the Hibernate/JPA Transaction API.
Because Spring uses AOP, the transaction management is decoupled from your business logic, which would not be the case if you were using the programmatic Hibernate/JPA Transaction API.
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
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.