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 ?
It works because you are lucky enough. Lucky enough means that commit and begin are called in right order – accidentally.
You do use single instance of entity manager from multiple threads. That is wrong thing to do, because it is not guaranteed to be thread safe. Access to resource level transaction via EntityTransaction is bound to entity manager instance, not to the thread.
So result is that you are sharing same EntityTransaction and using it luckily serially for multiple transactions. Using it serially to strart and end multiple transaction is fine, but using it from many threads is not.
In hibernate (4.1.4) reference is stored to tx instance field in AbstractEntityManageImpl class, but that is just implementation detail.