1、背景

在我们的日常开发中,经常会存在在一个Service层中调用另外一个Service层的方法。比如:我们有一个TaskService,里面有一个execTask方法,且这个方法存在事务,这个方法在执行完之后,需要调用LogService的insertLog方法记录一条日志,这个方法上也有事务,不管日志记录成功还是失败,都不能影响execTask方法的执行。因此我们很容易写出如下代码。

@Transactional
public void execTaskV1(){
log.info("开始执行任务");
try {
logService.insertLogV1();
} catch (Exception e) {
log.error("添加日志出现错误");
}
log.info("完成任务执行");
}

思考: 上方的代码,如果insertLogV1跑出了异常,execTaskV1方法的事务可以正常提交吗?

2、异常是如何实现出现的

1、了解Spring事务的传播属性

传播行为 描述 应用场景 行为特点
Propagation.REQUIRED 如果当前存在事务,则加入该事务;如果当前没有事务,则启动一个新的事务。 大多数场景,如多个方法需要在同一个事务中完成。 - 如果当前事务存在,方法执行在当前事务上下文中。
- 如果当前事务不存在,创建新事务。
Propagation.SUPPORTS 如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务方式执行。 对事务支持没有强制要求的场景,如只读查询。 - 如果当前事务存在,方法执行在当前事务上下文中。
- 如果当前事务不存在,以非事务方式执行。
Propagation.MANDATORY 如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。 必须在一个已存在的事务中执行的场景。 - 必须在已有事务中执行,否则抛出 IllegalTransactionStateException
Propagation.REQUIRES_NEW 每次调用该方法时都会启动一个新的事务。当前事务(如果有)会被挂起。 需要独立事务的场景,如日志记录或独立的业务操作。 - 总是创建新事务。
- 当前事务(如果有)会被挂起,直到新事务完成。
Propagation.NOT_SUPPORTED 总是以非事务方式执行,并且暂停当前事务(如果有)。 不需要事务的场景,如简单的查询操作。 - 总是以非事务方式执行。
- 暂停当前事务(如果有)。
Propagation.NEVER 总是以非事务方式执行,如果当前存在事务,则抛出异常。 严格禁止事务的场景,如某些非事务性操作。 - 必须在非事务上下文中执行,否则抛出 TransactionException
Propagation.NESTED 如果当前存在事务,则在嵌套事务内执行;如果当前没有事务,则启动一个新的事务。 需要嵌套事务的场景,如复杂的业务流程中需要独立的回滚点。 - 如果当前事务存在,创建一个嵌套事务(依赖于数据库支持)。
- 如果当前事务不存在,创建新事务。

2、模拟异常出现

Transaction rolled back because it has been marked as rollback-only 这个异常在上述的案例中是如何实现的呢?



从上图中可知,出现了Transaction rolled back because it has been marked as rollback-only这个异常,那么这个异常是如何出现的呢?

其实这个是和Spring事务的传播属性Propagation有关。

默认情况下@Transaction的传播属性是Propagation.REQUIRED, 即如果当前存在事务,则加入该事务;如果当前没有事务,则启动一个新的事务。 在我们的例子中,事务的隔离级别都是Propagation.REQUIRED,即是在同一个事务中,因此insertLogV1方法抛出异常后,虽然上层捕获到了,但其实这个时候这个事务已经被标记成回滚状态了,因此事务无法提交成功。

如何解决: 只需要修改insertLogV1事务的传播属性为Propagation.REQUIRES_NEW即可。

3、完整代码

完整代码-https://gitee.com/huan1993/spring-cloud-parent/tree/master/springboot/springboot-transaction-v1

Transaction rolled back because it has been marked as rollback-only问题解决的更多相关文章

  1. “Transaction rolled back because it has been marked as rollback-only”

    spring的声明事务提供了强大功能,让我们把业务关注和非业务关注的东西又分离开了.好东西的使用,总是需要有代价的.使用声明事务的时候,一 个不小心经常会碰到“Transaction rolled b ...

  2. Transaction rolled back because it has been marked as rollback-only

    出现这种错误的原因 1.接口A 调用了接口B 2.接口B报异常了,没有在B里面进行try catch捕获 3.接口A对 接口B进行了try catch捕获 因为接口B报异常 会把当前事物A接口的事物( ...

  3. 【Spring】21、用spring目标对象处理Transaction rolled back because it has been marked as rollback-only

    在使用spring做事务管理时,很多人都会遇到这样一段异常: org.springframework.transaction.UnexpectedRollbackException: Transact ...

  4. Transaction rolled back because it has been marked as rollback-only分析解决方法

    1. Transaction rolled back because it has been marked as rollback-only事务已回滚,因为它被标记成了只回滚<prop key= ...

  5. 【springcloud】Transaction rolled back because it has been marked as rollback-only

    问题: 一个ajax请求,发生系统错误,错误内容:Transaction rolled back because it has been marked as rollback-only 原因是调用的s ...

  6. [转]Spring事务嵌套引发的血案---Transaction rolled back because it has been marked as rollback-only

    原文地址:https://blog.csdn.net/f641385712/article/details/80445912 1.概述 想必大家一想到事务,就想到ACID,或者也会想到CAP.但笔者今 ...

  7. @Transactional事务回滚异常:Transaction rolled back because it has been marked as rollback-only

    问题描述 事务设置手动回滚:TransactionAspectSupport.currentTransactionStatus().setRollbackOnly() 代码需要返回比较友好的提示,但t ...

  8. Transaction rolled back because it has been marked as rollback-only 原因 和解决方案

    产生原因  , 1 serviceA 调用 serviceB 然后 B  抛出异常 ,B 所在的 事物 回滚,B 把当前可写 事物标记成 只读事物 , 2 如果 A 和B 是在 同一个事物环境,并且 ...

  9. Spring事务嵌套引发的问题--Transaction rolled back because it has been marked as rollback-only

    转载https://blog.csdn.net/f641385712/article/details/80445912 读了两边才找到问题

  10. 记一次org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only异常

    @Transactional(rollbackFor = Exception.class) @Overridepublic DubboResult<Boolean> productAddO ...

随机推荐

  1. 大模型推理指南:使用 vLLM 实现高效推理

    本文主要分享如何使用 vLLM 实现大模型推理服务. 1. 概述 大模型推理有多种方式比如 最基础的 HuggingFace Transformers TGI vLLM Triton + Tensor ...

  2. npm报错error:0308010C:digital envelope routines::unsupported

    error:0308010C:digital envelope routines::unsupported 出现这个错误是因为 node.js V17版本中最近发布的OpenSSL3.0, 而Open ...

  3. Python源码分析2 - 一个简单的Python程序的执行

    本文主要通过跟踪一个非常简单的Python程序的执行,简单讨论Python实现的基本框架和结构. 要执行Python程序如下,功能非常简单:从1加到10再打印出来 # test program sum ...

  4. openjdk和jdk的区别与联系

    使用过LINUX的人都应该知道,在大多数LINUX发行版本里,内置或者通过软件源安装JDK的话,都是安装的openjdk,那么到底什么是openjdk,它与sun jdk有什么关系和区别呢?历史上的原 ...

  5. 性能调优、虚拟机、垃圾回收、软硬件协调相关文章和视频 — Part1

    本文由 ImportNew - 顾星竹 翻译自 javacodegeeks.如需转载本文,请先参见文章末尾处的转载要求. ImportNew注:如果你也对Java技术翻译分享感兴趣,欢迎加入我们的 J ...

  6. confd+Nacos实现nginx配置文件管理

    场景: 由于公司内部站点保护的需求, 将部分的站点添加白名单, 这边的操作是在nginx配置文件中添加如下代码 allow 127.0.0.1: deny all; 但随之问题也出现了, 需要添加一个 ...

  7. 运维工具之Netdata

    [导语]:Netdata 是一个开源.免费.预配置.高灵敏度的分布式实时监控系统. 简介 Netdata的分布式实时监视代理以零配置的方式,从系统.硬件.容器和应用程序收集数千个指标,它可以运行在所有 ...

  8. 面试官:来谈谈Vue3的provide和inject实现多级传递的原理

    前言 没有看过provide和inject函数源码的小伙伴可能觉得他们实现数据多级传递非常神秘,其实他的源码非常简单,这篇文章欧阳来讲讲provide和inject函数是如何实现数据多级传递的.ps: ...

  9. arcgis技术文章索引

    1.Error:  The System Clock has been set back to the past. 点击打开链接 2.Error:  Error 1500. Another insta ...

  10. Ant Design Pro项目Popover位置微调

    前情 公司有经常需要做一些后台管理页面,我们选择了Ant Design Pro,它是基于 Ant Design 和 umi 的封装的一整套企业级中后台前端/设计解决方案. 产品效果图 最新接到的一个后 ...