调用存储过程报错No externally managed transaction如何修复
问题解决方案
No externally managed transaction is currently active for this thread错误的核心原因是:你给方法标注了@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED),该属性会挂起当前线程的所有托管事务,导致方法执行时没有活跃的事务上下文,而JPA的query.executeUpdate()操作要求必须运行在事务环境中。
方案1:使用容器声明式事务(推荐)
根据业务需要修改事务属性即可:
- 如果允许该方法加入当前已存在的事务,使用默认的
REQUIRED属性,直接删除原有的NOT_SUPPORTED注解即可(无特殊配置时@TransactionAttribute默认值就是REQUIRED) - 如果需要该方法运行在独立的新事务中(比如存储过程内部有DDL操作、执行结果不需要回滚到父事务等场景),修改为
REQUIRES_NEW属性
修改后的代码示例:
@Override @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) public void rebuildIndexes() { Query query = getEm().createNativeQuery("BEGIN OFPA_ARCHIVING.rebuild_archiving_indexes; END;"); query.executeUpdate(); }
方案2:手动管理事务(仅适用于非容器托管的EntityManager场景)
如果你确实不需要容器托管的外部事务,可以手动开启EntityManager的本地事务:
@Override @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED) public void rebuildIndexes() { EntityManager em = getEm(); EntityTransaction tx = em.getTransaction(); try { tx.begin(); Query query = em.createNativeQuery("BEGIN OFPA_ARCHIVING.rebuild_archiving_indexes; END;"); query.executeUpdate(); tx.commit(); } catch (Exception e) { if (tx.isActive()) { tx.rollback(); } throw e; } }
内容的提问来源于stack exchange,提问作者Klajdi
相关产品推荐
相关产品推荐

