首页 > 其他分享 >两个事务方法导致异常抛出Transaction rolled back because it has been marked as rollback-only

两个事务方法导致异常抛出Transaction rolled back because it has been marked as rollback-only

时间:2024-05-07 11:01:57浏览次数:24  
标签:事务 Transaction rolled 异常 回滚 been class 方法 public

异常现场(背景)

在springboot事物操作开发中,如果A方法调用B方法,A和B方法都在不同的类中,且A和B都加了@Transactional注解,A调用B方法时,将B方法try catch了。
代码:

@Service  
public class BService {  
      
    @Transactional(rollbackFor = Exception.class) 
    public void bMethod() {  
        // ... 业务逻辑 ...    
        throw new RuntimeException("B方法异常");  
    }  
}  

@Service  
public class AService {  
      
    @Autowired  
    private BService bService;  

    @Transactional(rollbackFor = Exception.class)  
    public void aMethod() {  
        try {  
            bService.bMethod();  
        } catch (Exception e) {  
            // 处理B方法的异常 
            // 可以记录日志或采取其他措施  
        }  
        // A方法的其他逻辑,继续执行  
    }  
}

问题产生原因

在Spring框架中,当使用@Transactional注解时,事务的边界通常是由Spring的AOP代理来控制的。如果在事务中发生异常并且没有被捕获,Spring会标记当前事务为“只回滚”(rollback-only),并在事务的边界处(通常是方法的退出点)执行回滚。
当A方法调用B方法,并且B方法因为异常而回滚了,但由于A方法捕获了异常并没有重新抛出,所以A方法的事务不会自动回滚,但由于B方法的事务已经被标记为“只回滚”,当A方法的事务试图提交时,它会发现它处于“只回滚”状态,并抛出一个异常,提示:Transaction rolled back because it has been marked as rollback-only

解决方式

现在的需求是,想要A继续执行不抛出异常,如果A异常,A的方法也会回滚,B异常也正常回滚,但B是单独的事务。很简单,如果B方法是一个可以独立处理其事务逻辑的服务,并且不需要A方法的事务上下文,可以让B方法独立地处理其事务。这样,B方法的异常就不会影响A方法的事务。
代码:

@Service  
public class BService {  
      
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
    public void bMethod() {  
        // ... 业务逻辑 ...  
        // 如果这里抛出异常,只有B的事务会回滚  
        throw new RuntimeException("B方法异常");  
    }  
}  

@Service  
public class AService {  
      
    @Autowired  
    private BService bService;  

    @Transactional(rollbackFor = Exception.class)  
    public void aMethod() {  
        try {  
            bService.bMethod();  
        } catch (Exception e) {  
            // 处理B方法的异常,但A方法的事务不会受到影响  
            // 可以记录日志或采取其他措施  
        }  
        // A方法的其他逻辑,继续执行  
    }  
}

标签:事务,Transaction,rolled,异常,回滚,been,class,方法,public
From: https://www.cnblogs.com/qukun/p/18176734

相关文章

  • DAPPER 事务 TRANSACTION
    https://www.cnblogs.com/friend/p/16754184.html\ publicasyncTask<int>Save(longmoldProducedProductId,List<MoldStandardResource>list){intresult=0;stringdelSql="DeleteMoldStandardResourceWhereMoldProducedProductId......
  • [转帖]MySQLdump之single-transaction详解
     作者:@张扶摇本文为作者原创,转载请注明出处:https://www.cnblogs.com/zhangshengdong/p/9196128.html目录MySQLdump之single-transaction详解single-transaction保存点的日志分析查看当前会话级别导出文件的字符集类型MySQLdump之single-transaction详解single-transact......
  • fastjson导致的程序崩溃:A fatal error has been detected by the Java Runtime Enviro
    ##AfatalerrorhasbeendetectedbytheJavaRuntimeEnvironment:##EXCEPTION_ACCESS_VIOLATION(0xc0000005)atpc=0x000001da4d3ab6b3,pid=15996,tid=0x0000000000006478##JREversion:Java(TM)SERuntimeEnvironment(8.0_361)(build1.8.0_361-b09)......
  • Java开启事务(@Transactional)
    开始事务的代码可以使用Spring的事务管理器来实现。具体步骤如下:1.在Spring配置文件中配置事务管理器和事务通知器:```<beanid="transactionManager"class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><propertyname="dataSource"ref="......
  • 浅谈@Transactional 注解的使用
    在SpringBoot的开发项目中,在Controller控制层,我们一般只做入参的校验;在Service服务层,我们把业务逻辑都写在这里,在服务层的方法中,我们会调用其它的服务层接口或者mapper层方法,所以,需要在服务层的方法上,我们需要增加:@Transactional(rollbackFor=Exception.class)添加该注解后......
  • DbMigrator迁移数据库报错:The ConnectionString property has not been initialized.
    问题执行.DbMigrator时报错:TheConnectionStringpropertyhasnotbeeninitialized.原因情况一DbContext中没有指定连接字符串解决方案情况二appsettings.json配置文件的属性没有设置为始终复制解决方案右键appsettings.json选择属性>复制到输出目录选择始终复制或......
  • Chrome跨域问题:查看图片报错has been blocked by CORS policy: The request client is
    Chrome跨域问题:hasbeenblockedbyCORSpolicy:Therequestclientisnotasecurecontextandtheresourceisinmore-privateaddressspaceprivate已被CORS策略阻止:请求客户端不是安全上下文,资源位于更私有的地址空间私有问题原因:公网资源(访问者)访问私网资源......
  • Lock wait timeout exceeded; try restarting transaction 问题分析
    问题描述在项目中有一个MySQL数据库归档程序,每天会定时跑,在归档逻辑中,会涉及到对大表的查询(根据创建时间查询,它是索引),这个过程中会锁数据(行级锁),然后我们插入新的数据就会报错:获取锁超时Causedby:com.mysql.cj.jdbc.exceptions.MySQLTransactionRollbackException:Lockwait......
  • CommandNotFoundError: Your shell has not been properly configured to use 'conda
    当使用condaactivatemy_env激活环境时,可能会遇到如下错误:CommandNotFoundError:Yourshellhasnotbeenproperlyconfiguredtouse'condaactivate'.Toinitializeyourshell,run$condainit<SHELL_NAME>Currentlysupportedshellsare:-bash......
  • Transaction rolled back because it has been marked as rollback-only
    背景最近在看程序日志的时候,发现频繁出现Transactionrolledbackbecauseithasbeenmarkedasrollback-only这个异常,查了很久资料才知道是什么原因导致抛出这异常的,下面解析一下;原因字面上的意思就是:事务已回滚,因为它已被标记为仅回滚,那为什么会标记为仅回滚呢?其实原因就......