jpa transaction 回滚_如何让Spring @Transactional回滚所有未捕获的异常?

我的Spring / Java Web应用程序具有可以触及数据库的@Transactional服务:

@Transactional

public class AbstractDBService { ... }

所需的功能适用于任何未被捕获的throwable,它会在服务层之外传播,从而导致回滚.有点惊讶这不是默认行为,但经过一些谷歌搜索后尝试:

@Transactional(rollbackFor = Exception.class)

这似乎有效,除非故意吞下异常并且不再重新抛出异常. (特殊情况是当找不到实体时.猜测这可以重新设计为不抛出异常,但期望不可避免地存在其他异常 – 例如,当使用Thread.sleep()时,一个想到的是InterruptedException.然后春天抱怨:

org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is

javax.persistence.RollbackException: Transaction marked as

rollbackOnly

…truncated..

Caused by: javax.persistence.RollbackException: Transaction marked as rollbackOnly

at org.hibernate.jpa.internal.TransactionImpl.commit(TransactionImpl.java:58)

at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:517)

我在这里错过了什么吗?…有没有办法告诉Spring回滚所有未被捕获的扔掉的东西?

解决方法:

如果要回滚所有未捕获的Throwable,可以在注释中指定:

@Transactional(rollbackFor = Throwable.class)

默认情况下,Spring不会为Error子类回滚,可能是因为一旦抛出一个错误,JVM将处于一个足够好的状态,无论如何都要对它做任何事情似乎都是值得怀疑的,此时事务可能会超时. (如果在引发OutOfMemoryError时尝试回滚,最可能的结果是另一个OutOfMemoryError.)因此,您可能无法获得太多收益.

当你提到吞下一个异常的情况时,Spring不可能知道它,因为异常没有找到Spring的代理(它实现了事务功能).这就是你的RollbackException示例中发生的事情,Hibernate已经发现事务需要回滚但是Spring没有得到备忘录,因为有人吃了这个例外.所以Spring没有回滚事务,它认为一切正常并尝试提交,但由于Hibernate标记了事务回滚,提交失败.

答案是不要吞下这些例外,而是让它们被抛出;让它们不受控制应该会让你更容易做正确的事情.应该设置一个异常处理程序来接收从控制器抛出的异常,在应用程序的任何级别抛出的大多数异常都可以被捕获并记录.

标签:java,spring,jpa,hibernate,transactions

来源: https://codeday.me/bug/20190724/1526537.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值