Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How JPA transactions works

Following code gets executed whenever I want to persist any entity. Things seems to be working fine but I fail to understand how it works !

EntityManager em = getEntityManager();
EntityTransaction userTransaction = em.getTransaction();
userTransaction.begin();
em.persist( ent );
userTransaction.commit();

The EntityManager above is a single instance shared by whole application. After starting the transaction; I just say em.persist(entity).. How does hibernate know it belongs to which transaction !

Suppose there are 10 concurrent users on my application and all 10 threads executing above code. So 10 independent transactions are getting created and committed. But all 10 different entities I am not associating them with their respective transactions; so how is JPA able to work it out !

Based on answers; we have below; are we saying that we should have an EntityManager instance per thread ? Will that not be a kill on the server ! Should we be pooling these instances ? Will it not be equal to again implementing sort of Connection Pooling ?

like image 866
Deepak Singhal Avatar asked Jun 27 '12 07:06

Deepak Singhal


People also ask

How does JPA transaction work?

Transactions and Proxies. At a high level, Spring creates proxies for all the classes annotated with @Transactional, either on the class or on any of the methods. The proxy allows the framework to inject transactional logic before and after the running method, mainly for starting and committing the transaction.

How are transactions handled in Spring data JPA?

Spring Boot and Spring Data JPA make the handling of transactions extremely simple. They enable you to declare your preferred transaction handling and provide seamless integration with Hibernate and JPA. The only thing you need to do is to annotate one of your methods with @Transactional.

How do Spring boot transactions work?

Spring Boot implicitly creates a proxy for the transaction annotated methods. So for such methods the proxy acts like a wrapper which takes care of creating a transaction at the beginning of the method call and committing the transaction after the method is executed.

What are the types of transactions supported by JPA?

There are two main types of transactions: JTA transactions and resource-local transactions. In the case of different entities managers types, JPA has some limitation of using them.


1 Answers

It's using ThreadLocal variables for the Transaction.

See also the documentation for UserTransaction:

begin()
Create a new transaction and associate it with the current thread.

You should not share the EntityManager though since it is not guaranteed to be thread-safe.

However if you are injecting it in an EJB, you don't have to worry about thread-safety: http://www.adam-bien.com/roller/abien/entry/is_in_an_ejb_injected

If you are using Spring to inject it, you'll get a thread-safe proxy: http://static.springsource.org/spring/docs/3.1.1.RELEASE/spring-framework-reference/html/orm.html#orm-jpa-straight

Although EntityManagerFactory instances are thread-safe, EntityManager instances are not. The injected JPA EntityManager behaves like an EntityManager fetched from an application server's JNDI environment, as defined by the JPA specification. It delegates all calls to the current transactional EntityManager, if any; otherwise, it falls back to a newly created EntityManager per operation, in effect making its usage thread-safe.

like image 154
Sandro Avatar answered Nov 16 '22 03:11

Sandro