当前位置: 首页 > news >正文

解决Could not commit JPA transaction RollbackException: Transaction marked as rollbackOnly

项目测试发生问题,方法正常结束,但是报了

Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Transaction marked as rollbackOnly org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Transaction marked as rollbackOnly
    at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:521)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:393)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:120)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:622)

错误,问什么不能提交呢?

经过查找发现了这么一段话

I finally understood the problem:

methodA() {
    methodB()
}

@Transactional(noRollbackFor = Exception.class)
methodB() {
    ...
    try {
        methodC()
    } catch (...) {...}
    log("OK");
}

@Transactional
methodC() {
    throw new ...();
}
What happens is that even though the methodB has the right annotation, the methodC does not. When the exception is thrown, the second @Transactional marks the first transaction as Rollback only anyway.

原来,在一个transactional中如果有另一transaction发生了异常,即使你捕捉了这个异常,那么Transaction也会被定义成RollbackOnly,这也正是事务管理的原则,可是我的系统哪里出异常了呢?

原来,spring jpa JpaRepository的实现方法中用ID删除的源码是这样的

@Transactional
    public void delete(ID id) {

        Assert.notNull(id, ID_MUST_NOT_BE_NULL);

        T entity = findOne(id);

        if (entity == null) {
            throw new EmptyResultDataAccessException(String.format("No %s entity with id %s exists!",
                    entityInformation.getJavaType(), id), 1);
        }

        delete(entity);
    }

他是这样实现的,先查找这个ID的对象看是否存在如果不存在则直接抛出一个非检查型异常,就不再执行delete操作。这和我平常习惯认为的不太一样,一般我习惯删除没有的记录不会报错,执行sql也是这样的。而我只是在外面捕捉了这个异常,所以发生的这样的问题。

 

转载于:https://www.cnblogs.com/fashflying/p/5669228.html

相关文章:

  • Linux下使用mke2fsk格式化虚拟磁盘分区的方法
  • ios KVOKVC
  • 开源入侵检测系统OSSEC搭建之二:客户端安装
  • Cisco设备型号编码详解
  • Android 通知栏自定义视图并且设置事件的开发
  • VirtualBox 安装过程中出现 Running VMs found 错误的解决过程
  • ubuntu 访问window
  • Java垃圾收集调优实战
  • jqeury轮播图插件 简单教程(适合新手)
  • android 文件的权限
  • 研磨设计模式之 策略模式--转
  • Android 完美退出 App (Exit)
  • 初识 linux 正则表达式
  • swift - UILabel的用法
  • 抽象类是否可继承实体类的问题
  • 【407天】跃迁之路——程序员高效学习方法论探索系列(实验阶段164-2018.03.19)...
  • C语言笔记(第一章:C语言编程)
  • Fastjson的基本使用方法大全
  • JS题目及答案整理
  • Linux编程学习笔记 | Linux IO学习[1] - 文件IO
  • Next.js之基础概念(二)
  • React-生命周期杂记
  • select2 取值 遍历 设置默认值
  • Swift 中的尾递归和蹦床
  • 番外篇1:在Windows环境下安装JDK
  • 浮动相关
  • 小程序01:wepy框架整合iview webapp UI
  • 终端用户监控:真实用户监控还是模拟监控?
  • #调用传感器数据_Flink使用函数之监控传感器温度上升提醒
  • #每日一题合集#牛客JZ23-JZ33
  • (arch)linux 转换文件编码格式
  • (windows2012共享文件夹和防火墙设置
  • (附源码)基于ssm的模具配件账单管理系统 毕业设计 081848
  • (牛客腾讯思维编程题)编码编码分组打印下标(java 版本+ C版本)
  • (七)Knockout 创建自定义绑定
  • (一)UDP基本编程步骤
  • (转)memcache、redis缓存
  • (转)详解PHP处理密码的几种方式
  • *ST京蓝入股力合节能 着力绿色智慧城市服务
  • .gitignore文件---让git自动忽略指定文件
  • .NET Core实战项目之CMS 第一章 入门篇-开篇及总体规划
  • .NET Framework杂记
  • .NET MVC、 WebAPI、 WebService【ws】、NVVM、WCF、Remoting
  • .Net Web项目创建比较不错的参考文章
  • .NET值类型变量“活”在哪?
  • /etc/fstab和/etc/mtab的区别
  • @LoadBalanced 和 @RefreshScope 同时使用,负载均衡失效分析
  • @test注解_Spring 自定义注解你了解过吗?
  • @Transactional类内部访问失效原因详解
  • [BT]BUUCTF刷题第9天(3.27)
  • [C++] 统计程序耗时
  • [ccc3.0][数字钥匙] UWB配置和使用(二)
  • [CentOs7]图形界面
  • [Hadoop in China 2011] Hadoop之上 中国移动“大云”系统解析
  • [HAOI2016]食物链