When I add @Async, entityManager.flush() will raise an exception

后端 未结 2 647
失恋的感觉
失恋的感觉 2020-12-18 11:24

I\'m using Spring framework.

The structure of my project is Controller ➡️ Service ➡️ Logic.

I added @Transactional in Logic cla

相关标签:
2条回答
  • 2020-12-18 12:25

    I think this is a bug.

    • With No @Async
      • When request comes, TransactionSynchronizationManager.bindResource((Object key, Object value) will be called, and a new EntityManager will be bound to current thread.
      • Then, EntityManagerFactoryUtils.doGetTransactionalEntityManager(EntityManagerFactory emf, @Nullable Map<?, ?> properties, boolean synchronizedWithTransaction) is called to get the bound EntityManager. Inside this method, it will call EntityManager.joinTransaction(). This method will call JdbcResourceLocalTransactionCoordinatorImpl.getTransactionDriverControl() to initialize TransactionDriverControlImpl physicalTransactionDelegate.
      • When we call EntityManager.flush(). JdbcResourceLocalTransactionCoordinatorImpl.isJoined()will be called to check.
    • With @Async
      • When request comes, TransactionSynchronizationManager.bindResource((Object key, Object value) will be called, and a new EntityManager will be bound to current thread.
      • If there is a @Async, a new thread will be created.
      • Then, EntityManagerFactoryUtils.doGetTransactionalEntityManager(EntityManagerFactory emf, @Nullable Map<?, ?> properties, boolean synchronizedWithTransaction) is called to get the bound EntityManager. But in this new thread, there is no bound EntityManager, so a new one will be created, but EntityManager.joinTransaction() will not be called. So TransactionDriverControlImpl physicalTransactionDelegate will not be initialized.
      • When we call EntityManager.flush(). Since TransactionDriverControlImpl physicalTransactionDelegate is null, an exception will be raised.

    Why EntityManager.joinTransaction() is not called when a new EntityManager is created in a new thread?

    0 讨论(0)
  • 2020-12-18 12:26

    I found the solution. Just add entityManager.joinTransaction();.

    0 讨论(0)
提交回复
热议问题