seata AT模式中,seata失效,RM(事务参与者) 没有访问undo_log 表,也没有生成undo_log日志记录 ,可是global_table区有日志 ,解决BUG!

在使用Seata进行分布式事务管理时遇到一个棘手问题:全局事务开启但未执行回滚,导致undo_log无记录。经过分析,发现是Seata的数据源代理配置出现了问题。通过手动添加并配置DataSourceProxy,同时关闭自动代理生产数据源,解决了该问题。补充说明,若启动时因Spring已存在数据源注入导致报错,可在配置中允许bean覆盖以解决问题。

在分布式系统中,相信大家一定听过阿里巴巴退出的seata , 刚好最近小弟也在研究seata , 搭建环境的时候遇到了一个坑 , 和大家分享一下 :

首先是我搭建了两个微服务 order 和 store , 注册中心使用的是nacos ,
简单的业务场景: 先下订单,然后减库存操作 , 在seata的加持下, 下单 和 减库存一定是同步成功,同步失败 ;
开始搭建环境 , 状态如下:

01 两个微服务连接上了 seata-server

在这里插入图片描述

02 seata-server 也发现了 order store 两个服务

在这里插入图片描述

03 上面两步 , 环境搭建成功了, 在业务上面加了@GlobalTransactional 然后发送请求测试 ,

在这里插入图片描述

04 执行的结果是报错了, 然而两个微服务(RM)的两个数据库都没有回滚 , seata没有起作用 !!!

琢磨了很久 , 自己完全是按照官方文档教程来搭建的啊 , 竟然还是出了问题 , 后面捣鼓了很久 , 惊讶地发现seata -server 日志显示 全局事务已经开启, global_table 都有了记录 , 唯独 undo_log没有访问记录!!!

**但是 global_table 有记录的 !!! **
在这里插入图片描述

seata-server 服务端也有日志记录, 并且生成了全局xid , 这说明seata服务已经工作, 开启了分布式事务 ;
在这里插入图片描述

于是大胆猜测肯定是两个微服务(事务参与者RM) 这边出了问题 , undo_log这边是一点动静都没有的(没有记录) , global_table 却有日志记录 , 网上找了很多资料, 也没有找到类似的问题 (挺好奇的, 大哥们就没有踩过类似的坑?) , 然后小弟各种试探 , 各种换版本 , 终于黄天不负有心人 , 捣鼓了好久 , 终于发现了问题 , 是因为seata的自动生成的代理数据源时候除了问题 , 添加了一个 seata数据代理 Bean , 并且将自动代理生产数据源置为false , 问题解决 , undo_log 也开始有了记录 ;

修改后继续发送localhost:8081/order/saveOrder 请求, seata如下 :
在这里插入图片描述

解决步骤:

第一步 : 添加自己的代理数据源
在这里插入图片描述
代码如下 :

    /**
     * 将阿里云提供的seata专用数据库连接池对象放入IOC容器
     */
   @Primary
    @Bean
    public DataSourceProxy dataSource(){
        DruidDataSource druidDataSource = new DruidDataSource();
        druidDataSource.setDriverClassName(driver);
        druidDataSource.setUrl(url);
        druidDataSource.setUsername(username);
        druidDataSource.setPassword(password);
        DataSourceProxy dsp = new DataSourceProxy(druidDataSource);
        return dsp;
    }

第二步: 并且将自动代理生产数据源置为false在这里插入图片描述

  enable-auto-data-source-proxy: false # 取消自动代理

虽然问题解决了, 可我还是有点疑惑 , spring alibaba seata 不是会自动代理生产数据源吗, 怎么到我这就失效了呢 ? 挺纳闷的 …

后续还会研究是啥原因 (为啥自动代理生产seata的数据源会失效) , 暂时先和大家分享这个bug , seata AT模式中 , nacos 注册中心 , 存储 db模式的情况下 , seata失效 , undo_log 没有日志记录 , 很有可能是因为seata 的代理数据源没有生效 , 自己手动生产即可 , 希望能帮助到大家 ;




补充: 部署能力强,启动无报错的小伙伴可以忽略下面这段补充
2023年5月23日17:29:14有小伙伴私信我, 代理数据连接池后,启动报错如下,
在这里插入图片描述
原因: spring已经注入了一个连接池, 在次注入就会报错 , 可以在yaml文件中加入允许注入IOC覆盖的配置 , 启动成功 , 问题解决 .
在这里插入图片描述

spring:
  main:
    allow-bean-definition-overriding: true
评论 17
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值