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

1万+

被折叠的 条评论
为什么被折叠?



