spring 事务问题:Transaction rolled back because it has been marked as rollback-only

2024-02-14 17:08

本文主要是介绍spring 事务问题:Transaction rolled back because it has been marked as rollback-only,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

问题描述:

同事测试时使用异常数据,代码报错但是并不是异常产生的错误,而出现:

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

中文翻译就是:

事务已回滚,因为它被标记成了只回滚

代码片段:

    // 我的代码@Transactional(readOnly = true, rollbackFor = Exception.class)public String select(String pid,String id) {List<Object> list = this.commonService.select(pid,id);if (CollectionUtils.isEmpty(list)) {throw new ApplicationException("查询数据异常");}... }.....// 调用代码@Transactional(readOnly = true, rollbackFor = Exception.class)public String select(String pid,String id) {try{// 针对异常进行捕获,但是没有抛出异常this.measureService.select(pid,id);}catch(ApplicationException e) {}}

错误原因分析:

A和B都有事务,A调用B,B中抛出了异常,A这边捕获B的异常,但是没有将异常抛出,导致A方法执行结束时,提交事务,出现了上述的错误

@Transactional原理:

@Transactional其内部是基于Aop实现的,

SpringAop异常捕获的原理:本拦截的方法需显示抛出异常,并不能经过任何处理,这样Aop代理才能捕获方法的异常,才能进行回滚,默认情况下Aop只捕获RuntimeException异常

这样原理就简单了,我们知道事务是可以继承的,那么A和B中可以理解为同一个事务,我们在B中进行了抛出了异常,然后再A中进行了捕获,但是没有抛出该异常,相当于在A中进行了处理,没有抛出该异常。细分下:B方法返回时,transcation已经被设置为rollback-only了,但是A这边捕获异常,没有继续向外抛,那么A方法结束时,就会由Aop来提交事务,但是此时transcation已经被设置为rollback-only了,所以就会抛出上述异常。

Rollback-only异常的解决:

1.B方法中我们可以手动捕获异常,并且处理该异常

        try {int i = 1/0;}catch (Exception e) {TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();}

2.B方法中的事务我们可以开启一个新的事务,与A中的事务不一样,这样A中出现异常回滚的事务与B中的事务不是同一个事务,这样话就可以避免上述的问题了,但是这样会出现一个问题,如果B中也有对数据的操作,那么B中出现异常,是不会让A中的事务回滚的。该方法适用于B中没有对数据的操作

// 在B中方法上添加注解,另开一个事务
@Transactional(propagation = Propagation.REQUIRES_NEW)

 

这篇关于spring 事务问题:Transaction rolled back because it has been marked as rollback-only的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/709102

相关文章

Java实现数据库图片上传与存储功能

《Java实现数据库图片上传与存储功能》在现代的Web开发中,上传图片并将其存储在数据库中是常见的需求之一,本文将介绍如何通过Java实现图片上传,存储到数据库的完整过程,希望对大家有所帮助... 目录1. 项目结构2. 数据库表设计3. 实现图片上传功能3.1 文件上传控制器3.2 图片上传服务4. 实现

Spring、Spring Boot、Spring Cloud 的区别与联系分析

《Spring、SpringBoot、SpringCloud的区别与联系分析》Spring、SpringBoot和SpringCloud是Java开发中常用的框架,分别针对企业级应用开发、快速开... 目录1. Spring 框架2. Spring Boot3. Spring Cloud总结1. Sprin

Java实现MD5加密的四种方式

《Java实现MD5加密的四种方式》MD5是一种广泛使用的哈希算法,其输出结果是一个128位的二进制数,通常以32位十六进制数的形式表示,MD5的底层实现涉及多个复杂的步骤和算法,本文给大家介绍了Ja... 目录MD5介绍Java 中实现 MD5 加密方式方法一:使用 MessageDigest方法二:使用

Java中的runnable 和 callable 区别解析

《Java中的runnable和callable区别解析》Runnable接口用于定义不需要返回结果的任务,而Callable接口可以返回结果并抛出异常,通常与Future结合使用,Runnab... 目录1. Runnable接口1.1 Runnable的定义1.2 Runnable的特点1.3 使用Ru

Java中Runnable和Callable的区别和联系及使用场景

《Java中Runnable和Callable的区别和联系及使用场景》Java多线程有两个重要的接口,Runnable和Callable,分别提供一个run方法和call方法,二者是有较大差异的,本文... 目录一、Runnable使用场景二、Callable的使用场景三、关于Future和FutureTa

Spring 中 BeanFactoryPostProcessor 的作用和示例源码分析

《Spring中BeanFactoryPostProcessor的作用和示例源码分析》Spring的BeanFactoryPostProcessor是容器初始化的扩展接口,允许在Bean实例化前... 目录一、概览1. 核心定位2. 核心功能详解3. 关键特性二、Spring 内置的 BeanFactory

Spring组件初始化扩展点BeanPostProcessor的作用详解

《Spring组件初始化扩展点BeanPostProcessor的作用详解》本文通过实战案例和常见应用场景详细介绍了BeanPostProcessor的使用,并强调了其在Spring扩展中的重要性,感... 目录一、概述二、BeanPostProcessor的作用三、核心方法解析1、postProcessB

Java导入、导出excel用法步骤保姆级教程(附封装好的工具类)

《Java导入、导出excel用法步骤保姆级教程(附封装好的工具类)》:本文主要介绍Java导入、导出excel的相关资料,讲解了使用Java和ApachePOI库将数据导出为Excel文件,包括... 目录前言一、引入Apache POI依赖二、用法&步骤2.1 创建Excel的元素2.3 样式和字体2.

Java实现将Markdown转换为纯文本

《Java实现将Markdown转换为纯文本》这篇文章主要为大家详细介绍了两种在Java中实现Markdown转纯文本的主流方法,文中的示例代码讲解详细,大家可以根据需求选择适合的方案... 目录方法一:使用正则表达式(轻量级方案)方法二:使用 Flexmark-Java 库(专业方案)1. 添加依赖(Ma

Spring Boot拦截器Interceptor与过滤器Filter详细教程(示例详解)

《SpringBoot拦截器Interceptor与过滤器Filter详细教程(示例详解)》本文详细介绍了SpringBoot中的拦截器(Interceptor)和过滤器(Filter),包括它们的... 目录Spring Boot拦截器(Interceptor)与过滤器(Filter)详细教程1. 概述1