如何手动控制JPA事务?共享EntityManager报错解决方案
手动控制JPA事务管理器的问题及解决
问题场景
我尝试手动提交JPA事务,最初编写的代码如下:
var tx = em.getTransaction(); for(var key : aggrFornitore.keySet()){ tx.begin(); try { var righe = aggrFornitore.get(key); jpaOperatingOnRepositories(key, righe, mSchede, mSettings); tx.commit(); } catch (Exception ex){ ex.printStackTrace(); tx.rollback(); } }
其中EntityManager通过Spring注入:
@PersistenceContext EntityManager em;
运行时抛出异常:
Not allowed to create transaction on shared EntityManager - use Spring transactions or EJB CMT instead
请问是否可以手动控制JPA事务管理器?
可行解决方案
感谢xerx593的建议,我将代码修改为使用Spring事务管理器手动控制事务,问题得以解决:
for(var key : aggrFornitore.keySet()){ var txDef = new DefaultTransactionDefinition(); txDef.setIsolationLevel(DefaultTransactionDefinition.ISOLATION_READ_COMMITTED); TransactionStatus transactionStatus = transactionManager.getTransaction(txDef); try { var righe = aggrFornitore.get(key); creaSingoloOrdine(key, righe, mSchede, mSettings); transactionManager.commit(transactionStatus); } catch (Exception ex){ ex.printStackTrace(); transactionManager.rollback(transactionStatus); } }
关键说明
通过@PersistenceContext注入的EntityManager属于共享EntityManager,这类实例由Spring容器统一管理,不允许直接调用getTransaction()手动开启事务,必须依托Spring的事务管理机制。
使用Spring的PlatformTransactionManager手动控制事务是完全可行的:
- 通过
DefaultTransactionDefinition自定义事务属性(如隔离级别) - 调用事务管理器的
getTransaction()获取事务状态 - 根据业务执行结果手动调用
commit()或rollback()完成事务控制
内容的提问来源于stack exchange,提问作者Roberto Petrilli
相关产品推荐
相关产品推荐

