Java CDI @PersistenceContext and thread safety

后端 未结 3 1766
粉色の甜心
粉色の甜心 2020-12-13 07:12

Is an EntityManager @Inject[ed] as follows in muliple classes threadsafe?

@PersistenceContext(unitName=\"blah\")
private EntityManager em;

3条回答
  •  夕颜
    夕颜 (楼主)
    2020-12-13 07:35

    Although EntityManager implementations itself are not thread safe the Java EE container injects a proxy which delegates all methods invocations to a transaction bound EntityManager. Therefore each transaction works with it's own EntityManager instance. This is true for at least transaction-scoped persistence context (which is default).

    If container would inject a new instance of EntityManager in each bean the below wouldn't work:

    @Stateless
    public class Repository1 {
       @EJB
       private Repository2 rep2;
    
       @PersistenceContext(unitName="blah", type = PersistenceContextType.TRANSACTION)
       private EntityManager em;
    
       @TransactionAttribute
       public void doSomething() {
          // Do something with em
          rep2.doSomethingAgainInTheSameTransaction();
       }
    }
    
    @Stateless
    public class Repository2 {
       @PersistenceContext(unitName="blah", type = PersistenceContextType.TRANSACTION)
       private EntityManager em;
    
       @TransactionAttribute
       public void doSomethingAgainInTheSameTransaction() {
          // Do something with em
       }
    }
    

    doSomething->doSomethingAgainInTheSameTransaction call happens in a single transaction and therefore the beans must share the same EntityManager. Actually they share the same proxy EntityManager which delegates calls to the same persistence context.

    So you are legal use EntityManager in singleton beans like below:

    @Singleton
    @ConcurrencyManagement(ConcurrencyManagementType.BEAN)
    public class Repository {
       @PersistenceContext(unitName="blah", type = PersistenceContextType.TRANSACTION)
       private EntityManager em;
    }
    

    Another proof is that there is no any mention of thread safety in EntityManager javadoc. So while you stay inside Java EE container you shouldn't care about concurrency access to EntityManager.

提交回复
热议问题