如何在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没有注入EntityManager
。 EntityManager
实例由实用程序类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不会导致事务被回滚。
更新:
确保一切正确
-
检查Spring确实创建了代理,并且您的方法正在事务中执行(例如,使用TransactionSynchronizationManager.isActualTransactionActive() )
-
检查
MyException.class
是否确实是未经检查的exception(java.lang.RuntimeException
或java.lang.Error
子类) -
检查你的exception是否确实被抛出(例如没有被捕获)
为什么你的控制器saveInfo()
被标记为事务? 这不推荐,只应将服务层标记为事务性。 例如,请看这篇文章。
也许entityManagerUtil(您在DAO实现中使用)使用或创建一个未在周围事务上下文中运行的实体管理器。 请看下面的教程 :这里JPA EntityManager注入了@PersistenceContext
你能确保你的persistenceUnit
配置了以下transaction type
(可选)和hibernate.connection.autocommit
为false
,如果没有请这样做。
为简洁起见,我排除了其他属性
@SpringLearner通过注释得到实体管理器持久化上下文层它会照顾回滚@PersistenceContext,实现你的问题中提到的场景样本,测试回滚它的工作正常并且我没有使用本机查询,它的简单示例你可以修改代码和test.it应该工作。
博客与git hub链接和完整的源代码