Seata 实现 springCloud 分布式(不同服务)分布式事物

参考官方文档: http://seata.io/zh-cn/

1、背景介绍

阿里巴巴自从跟SpringCloud共同发起创建微服务开源社区时,在生态内提供了一款适用于分布式应用程序(Dubbo、SpringCloud)的事务框架Seata,该框架经过多个大版本的发布,已经支持MySQL、Oracle这两种数据库事务回滚(Rollback)以及提交(Commit)控制,每次发版都会修复一些用户反馈的Issue以及添加一些新特性。

Seata(Fescar)是一种易于使用高性能,基于Java的开源分布式事务解决方案。

2、发展历程

TXC:淘宝事务构造器。 阿里巴巴中间件团队自2014年起启动该项目,以解决因应用程序架构从单体应用改为微服务而导致的分布式事务问题。
GTS:全局事务服务。 TXC作为Aliyun中间件产品,新名称GTS自2016年起发布。
Fescar:我们从2019年开始基于TXC / GTS开源开源项目Fescar,以便将来与社区密切合作。
Seata:2019年4月,更名为Seata,并调整开源计划。

3、术语

TC - 事务协调者

维护全局和分支事务的状态,驱动全局事务提交或回滚。

TM - 事务管理器

定义全局事务的范围:开始全局事务、提交或回滚全局事务。

RM - 资源管理器 (连接TC和TM类似中间人)

管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。
Seata 实现 springCloud 分布式(不同服务)分布式事物 - 图1

4、模式

这里主要使用AT模式

传统2pc

详细参考: https://www.cnblogs.com/qdhxhz/p/11167025.html
一阶段:请求阶段(commit-request phase,或称表决阶段,voting phase)
1、协调者节点向所有参与者节点询问是否可以执行提交操作,并开始等待各参与者节点的响应。
2、 各参与者节点响应协调者节点发起的询问。
如果参与者节点的事务操作实际执行成功,则它返回一个”同意”消息;
如果参与者节点的事务操作实际执行失败,则它返回一个”中止”消息。 有时候,第一阶段也被称作投票阶段,即各参与者投票是否要继续接下来的提交操作。
二阶段: 提交阶段(commit phase)
1、在该阶段,协调者将基于第一个阶段的投票结果进行决策:提交或取消。
2、当且仅当所有的参与者同意提交事务协调者才通知所有的参与者提交事务,
否则协调者将通知所有的参与者取消事务。参与者在接收到协调者发来的消息后将执行响应的操作。
弊端:
显而易见
1、 同步阻塞问题
2、 单点故障,单机故障导致数据不一致

传统3pc

三阶段提交协议(3PC)主要是为了解决两阶段提交协议的阻塞问题,2pc存在的问题是当协作者崩溃时,参与者不能做出最后的选择。因此参与者可能在协作者恢复之前保持阻塞。三阶段提交(Three-phase commit),是二阶段提交(2PC)的改进版本。
与两阶段提交不同的是,三阶段提交有两个改动点。
1、 引入超时机制。同时在协调者和参与者中都引入超时机制。
2、在第一阶段和第二阶段中插入一个准备阶段。保证了在最后提交阶段之前各参与节点的状态是一致的。
也就是说,除了引入超时机制之外,3PC把2PC的准备阶段再次一分为二
这样三阶段提交就有CanCommit、PreCommit、DoCommit三个阶段。
注:但是3PC依然没有完全解决数据不一致的问题。

seata基于传统2pc两阶段提交协议的演变:

一阶段:
业务数据和回滚日志记录在同一个本地事务中提交,释放本地锁和连接资源。
二阶段:
提交异步化,非常快速地完成。
回滚通过一阶段的回滚日志进行反向补偿。

5、最新版本的写法

配置数据源参考: https://github.com/seata/seata-samples/blob/master/doc/quick-integration-with-spring-cloud.md

1、依赖

2、yml配置

6、seata集群

这里基于 w10 测试,Linux同理
复制一份 seata ,两份的配置同样,这里有点类似eureka 的服务的客户端集群,不是eureka 集群
区别就是 加上一个 -n 数字(参数)
./seata-server.bat -p 8091 -h 127.0.0.1 -n 127.0.0.1:8092 -n 2
./seata-server.bat -p 8092 -h 127.0.0.1 -n 127.0.0.1:8091 -n 1
参数
-h: 注册到注册中心的ip
-p: Server rpc 监听端口
-m: 全局事务会话信息存储模式,file、db,优先读取启动参数
-n: Server node,多个Server时,需区分各自节点,用于生成不同区间的transactionId,以免冲突
-e: 多环境配置参考 http://seata.io/en-us/docs/ops/multi-configuration-isolation.html
-e 这里类似spring.profiles.active=test
eg: seata-server.sh -h 127.0.0.1 -p 8091 -m db -n 1 -e test
则会指定 registry-dev.conf
测试官方demo
主要将seata 提供的demo中 seata-samples\springcloud-eureka-feign-mybatis-seata项目运行起来

github的比较难下载,我是在qq群里面下载的。
我的github: https://github.com/tianliuzhen/dt-spring-cloud

1、首先启动 eureka

2、启动 seata-server

1、修改registry.conf
Seata 实现 springCloud 分布式(不同服务)分布式事物 - 图2
2、修改 file.conf
选择db 记得切换 数据库账号和密码

3、启动 seata-client
1、这里启动的是 官方demo里的两个demo
1、账号服务 account-server
2、订单服务 order-server
2、修改 registy.conf
2.1
Seata 实现 springCloud 分布式(不同服务)分布式事物 - 图3

3、修改 file.conf
Seata 实现 springCloud 分布式(不同服务)分布式事物 - 图4
Seata 实现 springCloud 分布式(不同服务)分布式事物 - 图5

采坑

1、no available server to connect

2、需要的sql脚本

3、Seata 配置中心实现原理

4、SEATA 1.0.0使用yaml配置替换file.conf 和 registry.conf

5、seata分布式事务tcc模式和at模式配置详解