配置了全局异常处理,如何保证分布式事务正常运行

本文探讨了在Spring Boot 2.2.2和Seata 1.4的微服务环境中,如何通过AOP解决全局异常导致的分布式事务未生效问题。作者提供了AT模式下使用@Aspect注解实现的异常回滚处理策略,并强调了在有全局异常处理的情况下,确保从属事务异常被捕捉的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

项目场景:

相关背景:
微服务场景下,配置了统一全局异常处理,导致seata在AT模式下无法正常回滚问题
spring boot版本 2.2.2 cloud 版本 Hoxton.RELEASE
seata版本1.4


问题描述:

假设服务A调用服务B, 服务B发生异常,由于全局异常处理的存在(@ControllerAdvice), seata 无法拦截到B服务的异常,从而导致分布式事务未生效

解决方案:

利用AOP拦截@GlobalTransactional 检查是否发生异常,如有异常,则回滚事务

上代码

/**
 * seata AT模式下事务异常回滚操作, 仅需在全局事务发起端配置此Handle
 */
@Slf4j
@Aspect
@Component
public class ATTransactionalHandler {

    @Pointcut("@annotation(io.seata.spring.annotation.GlobalTransactional)")
    public void txAnnotation(){

    }

    @AfterThrowing(throwing = "throwable", pointcut = "txAnnotation()")
    public void doAfterReturning(Throwable throwable) {
        GlobalTransaction globalTransaction = 
        GlobalTransactionContext.getCurrent();
        if (globalTransaction == null) {
            return;
        }

        log.info("AOP------- 全局事务回滚--
        ---xid:{}------》", globalTransaction.getXid());
        try {
            globalTransaction.rollback();
        } catch (TransactionException e) {
            e.printStackTrace();
        }
    }
}

由于AOP只能处理主事务端异常,而无法处理从事务端异常,而且我们配置了全局异常处理,所以rpc一定会有返回值
所以在每个全局事务方法最后, 需要判断rpc是否发生异常
发生异常则抛出RuntimeException, 配置的aop拦截则会回滚事务

rpc异常判断代码

评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值