前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Seata分布式任务出错排查

Seata分布式任务出错排查

作者头像
小四的技术之旅
发布2022-07-26 07:56:36
6050
发布2022-07-26 07:56:36
举报
文章被收录于专栏:小四的技术文章

前言

前段时间写了几篇关于分布式事务的文章,包括理论和实战,实战是以阿里的Seata来进行讲解,因为我们现在的系统中也大量使用分布式事务,只不过后端脚手架进行 二次封装,所以出问题得理解框架的原理和结构,才能更好地找到问题,最近我又加了一个模块进去,涉及好几个数据库的CRUD,所以为了保证数据的一致性,所以就必须得 使用分布式事务(只不过公司框架太过于封装,不太喜欢),过程中遇到一些问题,还有总结一些大家可能会遇到的问题,于是总结出来,供大家参考,可能一些问题是比较 幼稚的,不应该犯的,不够也没关系嘛,谁都会犯一些低级的错误,学会总结,然后下次避免。

下面是我总结的三个方面,分别是从数据表undo_log,服务是否引入SeataFeign调用问题来出发,当然,还有很多其他问题,比如使用不同的模式,也会出现其他问题, 我们使用的模式是file,如果使用dbredis,可能又会遇到其他问题。

分支事务库没有undo_log表

只要参与分布式事务的数据库,在库中都需要有undo_log表,undo_log表就是用来记录那一张表参与了分布式事务以及执行前和执行后的快照,以便对数据进行回滚,因为我们系统 使用的模式是file,自然就不需要global_table,branch_table,lock_table这三张表,所以就不用去看是否有这些表。

分支事务服务没有引入Seata

主事务是一个入口,然后从主事务处调用各个分支事务,主事务需要注册上seata-server,分支事务也需要注册上seata-server,如果没有加入seata依赖, 那么事务是无法注册上seata-server的,我在数据库中加了undo_log表后,事务依然无法回滚,于是我就debug一下,看undo_log里面是否有事务数据, 果然,主事务的undo_log中有事务数据,分支事务中undo_log无事务数据,那么很显然,分支事务没有接入Seata,于是在分支事务的微服务中引入seata依赖。

你以为成功了吗,然而并没有呢!分支事务依然没有回滚,虽然undo_log表中已经存入了数据,继续排查问题,看下面。

分支事务通过Feign接口调用,Feign接口处理了异常,导致主事务没有捕获到异常,导致事务无法回滚

分支事务微服务中引入了Seata依赖,在各个服务启动后,也都打印事务注册成功日志,然后执行后,分支事务异常依然没有回滚,于是看主事务接口打印的日志, 因为从主事务调用分支事务采用的是Feign方式调用,而我司使用的框架对Feign进行了全局异常处理,异常只在被调用的服务抛出,不会抛到调用服务,所以 分支事务抛出异常后,主事务没有感知到异常,因此不能对其进行回滚,因为我司框架对Feign进行全局异常捕获,所以光使用@GlobalTransactional注解 肯定不行。

于是就采用编码对事务进行回滚,图下,因为我们的Feign返回一个统一消息体,如果不为200,就标识失败,如果失败,那么就手动回滚事务,采用 GlobalTransactionContext.reload(RootContext.getXID()).rollback(),这样就能回滚事务。

代码语言:javascript
复制
     R response = messageClient.pushData(data);
     if (response.getCode() != 200) {
         try {
             GlobalTransactionContext.reload(RootContext.getXID()).rollback();
         } catch (TransactionException e) {
             e.printStackTrace();
         }
     }

如果我们的Feign没有对异常进行统一处理,那么异常就能抛到主事务所在的服务,那么就不用手动回滚事务,直接使用@GlobalTransactional就行,但是还有一个问题, 就是我们不要使用Feign的服务降级,如果使用服务降级,那么也需要对事务进行手动回滚,我们在使用Feign的时候通常会使用fallback,如果服务发生异常,那么 就对调用fallback所指定的类中的方法,因为fallback已经对异常进行处理,所以就导致主事务感知不到异常,所以就无法对事务进行回滚。

所以,要使分支事务能进行回滚,要么进行手动回滚,要么抛出异常(得让主事务感受到异常)。

今天的分享就到这里,感谢你的观看,我是小四,我们下期见

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-05-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 刘牌 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 分支事务库没有undo_log表
  • 分支事务服务没有引入Seata
  • 分支事务通过Feign接口调用,Feign接口处理了异常,导致主事务没有捕获到异常,导致事务无法回滚
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档