如何在entitymanager createNativeMethod中回滚

我正在使用本机方法的实体管理器,我想在发生一些错误时回滚。为此,我尝试了@Transactional注释,但这不回滚.Below是我的示例代码

调节器

 @Autowired ServiceImpl ServiceImpl; @RequestMapping("/saveinfo") @ResponseBody @Transactional public String saveinfo(Long id) { ServiceImpl.saveInfo(id); } 

服务类

 @Autowired DAOImpl daoImpl; @Transactional public String saveinfo(Long id) { daoImpl.saveInfo1(id); daoImpl.saveInfo12(id); daoImpl.saveInfo12(id); } 

DAOclass

 @Override public BigInteger saveInfo11() { Query query = entityManagerUtil.entityManager().createNativeQuery("insert query"); return (BigInteger)query.getSingleResult(); } @Override public BigInteger saveInfo12() { Query query = entityManagerUtil.entityManager().createNativeQuery("insert query"); return (BigInteger)query.getSingleResult(); } @Override public BigInteger saveInfo13() { Query query = entityManagerUtil.entityManager().createNativeQuery("insert query"); return (BigInteger)query.getSingleResult(); } 

现在在上面的代码中,

如果我在saveInfo3()有一些运行时错误,那么我想回滚saveInfo1()saveInfo2()

这是我的方式,但它没有回滚,所以请告诉我该怎么做

编辑

我试过用

 @Transactional(rollbackFor=MyException.class,propagation = Propagation.REQUIRED) and @Transactional(propagation = Propagation.REQUIRED) and @Transactional(rollbackFor=MyException.class)) 

在所有3个案例中,它都没有回滚

更新

 applicationcontext.xml   <!---->                        classpath*:META-INF/*.properties          

改进的控制器方法

 @Autowired ServiceImpl ServiceImpl; @RequestMapping("/saveinfo") @ResponseBody //Now I dont use transactional annotation in controller class public String saveinfo(Long id) { ServiceImpl.saveInfo(id); } 

如果需要更多信息,请询问

问题似乎是Spring没有注入EntityManagerEntityManager实例由实用程序类entityManagerUtil.entityManager() 。 这意味着,每次使用新的EntityManager ,它们都不是方法事务的一部分。

为了解决这个问题:让Spring正确注入EntityManager (例如尝试使用@PersistenceContext直接在原始bean中注入它,并在同一个方法中直接执行这三种方法)。


更新:问题是抛出exception的代码是在try / catch块中,这样,Spring没有回滚事务。 仅当事务方法以RuntimeException (默认情况下)退出时,才会回滚事务。

您需要将您的方法更改为@Transactional注释的rollbackFor属性,以便这样做

 @Transactional(rollbackFor=MyException.class) public String saveinfo(Long id) 

请记住, MyException应该是未经检查的exception,因为从@Transactional方法抛出的已检查exception不会导致事务被回滚。

更新:

确保一切正确

  1. 检查Spring确实创建了代理,并且您的方法正在事务中执行(例如,使用TransactionSynchronizationManager.isActualTransactionActive() )

  2. 检查MyException.class是否确实是未经检查的exception( java.lang.RuntimeExceptionjava.lang.Error子类)

  3. 检查你的exception是否确实被抛出(例如没有被捕获)

为什么你的控制器saveInfo()被标记为事务? 这不推荐,只应将服务层标记为事务性。 例如,请看这篇文章。

也许entityManagerUtil(您在DAO实现中使用)使用或创建一个未在周围事务上下文中运行的实体管理器。 请看下面的教程 :这里JPA EntityManager注入了@PersistenceContext

你能确保你的persistenceUnit配置了以下transaction type (可选)和hibernate.connection.autocommitfalse ,如果没有请这样做。

      

为简洁起见,我排除了其他属性

@SpringLearner通过注释得到实体管理器持久化上下文层它会照顾回滚@PersistenceContext,实现你的问题中提到的场景样本,测试回滚它的工作正常并且我没有使用本机查询,它的简单示例你可以修改代码和test.it应该工作。

博客与git hub链接和完整的源代码