架构设计 | 基于Seata中间件,微服务模式下事务管理
源码地址:GitHub·点这里 || GitEE·点这里
一、Seata简介
1、Seata组件
Seata是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata将为用户提供了AT、TCC、SAGA、XA事务模式,为用户打造一站式的分布式解决方案。
2、支持模式
AT 模式
- 基于支持本地 ACID 事务的关系型数据库。
- Java应用,通过 JDBC 访问数据库。
一阶段:业务数据和回滚日志记录在同一个本地事务中提交,释放本地锁和连接资源。
二阶段:提交异步化,非常快速地完成。回滚通过一阶段的回滚日志进行反向补偿。
TCC模式
一个分布式的全局事务,整体是两阶段提交的模型,全局事务是由若干分支事务组成的,分支事务要满足两阶段提交的模型要求,即需要每个分支事务都具备自己的:
一阶段 prepare 行为
二阶段 commit 或 rollback 行为
Saga模式
Saga模式是SEATA提供的长事务解决方案,在Saga模式中,业务流程中每个参与者都提交本地事务,当出现某一个参与者失败则补偿前面已经成功的参与者,一阶段正向服务和二阶段补偿服务都由业务开发实现。
XA模式
XA是一个分布式事务协议,对业务无侵入的分布式事务解决方案,XA提交协议需要事务参与者的数据库支持,XA事务具有强一致性,在两阶段提交的整个过程中,一直会持有资源的锁,性能不理想的缺点很明显。
二、服务端部署
1、下载组件包
1.2版本:seata-server-1.2.0.zip
解压目录
- bin:存放服务端运行启动脚本;
- lib:存放服务端依赖的资源jar包;
- conf:配置文件目录。
2、修改配置
file.conf配置
mode:db 即使用数据库存储事务信息,这里还可以选择file存储方式。
file模式为单机模式,全局事务会话信息内存中读写并持久化本地文件root.data,性能较高;
db模式为高可用模式,全局事务会话信息通过db共享,相应性能差些;
redis模式Seata-Server 1.3及以上版本支持,性能较高,存在事务信息丢失风险,请提前配置合适当前场景的redis持久化配置.
store {
## store mode: file、db
mode = "db"
db {
datasource = "druid"
dbType = "mysql"
driverClassName = "com.mysql.jdbc.Driver"
url = "jdbc:mysql://127.0.0.1:3306/seata_server"
user = "root"
password = "123456"
minConn = 5
maxConn = 30
globalTable = "global_table"
branchTable = "branch_table"
lockTable = "lock_table"
queryLimit = 100
maxWait = 5000
}
}
registry.conf配置
这里选择eureka作为注册中心,seata-server也要作为一个服务添加到注册中心,不使用配置中心所以config配置默认即可。
registry {
# file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
type = "eureka"
eureka {
serviceUrl = "http://localhost:8761/eureka"
application = "default"
weight = "1"
}
}
3、事务管理表
需要在seata-server即上述配置的MySQL库中建立3张事务管理表:
- 全局事务:global_table
- 分支事务:branch_table
- 全局锁:lock_table
- 事务回滚:undo_log
- SQL脚本:mysql-script目录
4、启动命令
Linux环境:sh seata-server.sh
三、业务服务搭建
1、代码结构

- seata-eureka:注册中心
- seata-order:订单服务
- seata-account:账户服务
- seata-inventor:库存服务
- seata-client:客户端服务
- account-feign:账户Feign接口
- inventory-feign:库存Feign接口
- order-feign:订单Feign接口
请求链路:客户端->订单->账户+库存,测试整个流程的分布式事务问题。
2、数据库结构

- seata_server:seata组件服务端依赖库
- seata_account:模拟账户数据库
- seata_inventor:模拟库存数据库
- seata_order:模拟订单数据库
各个库脚本位置:mysql-script/data-biz.sql
3、启动服务
依次启动:注册中心,库存服务,账户服务,订单服务,客户端服务;
Eureka服务列表如下:

四、Seata用法详解
1、Seata基础配置

几个基础服务的配置方式一样。
conf配置
file.conf重点关注下面内容,事务组的名称,需要在yml文件中使用。
my_test_tx_group = "default"
registry.conf:是注册中心的选择。
2、数据库配置
注意这里的事务组名称配置。
spring:
# 事务组的名称
cloud:
alibaba:
seata:
tx-service-group: my_test_tx_group
# 数据源配置
datasource:
type: com.alibaba.druid.pool.DruidDataSource
druid:
driverClassName: com.mysql.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/seata_account
username: root
password: 123456
将数据库整体由Seata进行代理管理,核心API:DataSourceProxy。
@Configuration
public class SeataAccountConfig {
@Value("${spring.application.name}")
private String applicationName;
@Bean
public GlobalTransactionScanner globalTransactionScanner() {
return new GlobalTransactionScanner(applicationName, "test-tx-group");
}
@Bean
@ConfigurationProperties(prefix = "spring.datasource.druid")
public DruidDataSource druidDataSource() {
return new DruidDataSource() ;
}
@Primary
@Bean("dataSource")
public DataSourceProxy dataSourceProxy(DataSource druidDataSource) {
return new DataSourceProxy(druidDataSource);
}
@Bean
public SqlSessionFactory sqlSessionFactory(DataSourceProxy dataSourceProxy)throws Exception{
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSourceProxy);
sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver()
.getResources("classpath*:/mapper/*.xml"));
sqlSessionFactoryBean.setTransactionFactory(new SpringManagedTransactionFactory());
return sqlSessionFactoryBean.getObject();
}
}
3、业务代码
核心注解:GlobalTransactional,管理整体的分布式事务。
@Service
public class OrderServiceImpl implements OrderService {
private final Logger LOGGER = LoggerFactory.getLogger(OrderServiceImpl.class);
@Resource
private OrderMapper orderMapper ;
@Resource
private AccountFeign accountFeign ;
@Resource
private InventoryFeign inventoryFeign ;
@GlobalTransactional
@Override
public Integer createOrder(String orderNo) {
LOGGER.info("Order 生成中 "+orderNo);
// 本服务下订单库
Integer insertFlag = orderMapper.insert(orderNo) ;
// 基于feign接口处理账户和库存
accountFeign.updateAccount(10L) ;
inventoryFeign.updateInventory(10) ;
return insertFlag ;
}
}
测试流程:在任意服务下抛出异常,观察整体的事务状态,观察是否有整体的事务控制效果。
五、源代码地址
GitHub地址:知了一笑
https://github.com/cicadasmile/spring-cloud-base
GitEE地址:知了一笑
https://gitee.com/cicadasmile/spring-cloud-base
推荐阅读:架构设计系列
架构设计 | 基于Seata中间件,微服务模式下事务管理的更多相关文章
- 2流高手速成记(之八):基于Sentinel实现微服务体系下的限流与熔断
我们接上回 上一篇中,我们进行了简要的微服务实现,也体会到了SpringCloudAlibaba的强大和神奇之处 我们仅改动了两个注释,其他全篇代码不变,原来的独立服务就被我们分为了provider和 ...
- 24 | 紧跟时代步伐:微服务模式下API测试要怎么做?
- 使用 Loki 微服务模式部署生产集群
转载自:https://mp.weixin.qq.com/s?__biz=MzU4MjQ0MTU4Ng==&mid=2247500523&idx=1&sn=0994af2b50 ...
- Java开发架构篇:领域驱动设计架构基于SpringCloud搭建微服务
作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言介绍 微服务不是泥球小单体,而是具备更加清晰职责边界的完整一体的业务功能服务.领域驱动 ...
- 基于 Docker 的微服务架构实践
本文来自作者 未闻 在 GitChat 分享的{基于 Docker 的微服务架构实践} 前言 基于 Docker 的容器技术是在2015年的时候开始接触的,两年多的时间,作为一名 Docker 的 D ...
- 通过Dapr实现一个简单的基于.net的微服务电商系统(十九)——分布式事务之Saga模式
在之前的系列文章中聊过分布式事务的一种实现方案,即通过在集群中暴露actor服务来实现分布式事务的本地原子化.但是actor服务本身有其特殊性,场景上并不通用.所以今天来讲讲分布式事务实现方案之sag ...
- iUAP云运维平台v3.0全面支持基于K8s的微服务架构
什么是微服务架构? 微服务(MicroServices)架构是当前互联网业界的一个技术热点,业内各公司也都纷纷开展微服务化体系建设.微服务架构的本质,是用一些功能比较明确.业务比较精练的服务去解决更大 ...
- 用友iuap云运维平台支持基于K8s的微服务架构
什么是微服务架构? 微服务(MicroServices)架构是当前互联网业界的一个技术热点,业内各公司也都纷纷开展微服务化体系建设.微服务架构的本质,是用一些功能比较明确.业务比较精练的服务去解决更大 ...
- (转)微服务架构 互联网保险O2O平台微服务架构设计
http://www.cnblogs.com/Leo_wl/p/5049722.html 微服务架构 互联网保险O2O平台微服务架构设计 关于架构,笔者认为并不是越复杂越好,而是相反,简单就是硬道理也 ...
随机推荐
- Vue 修饰符sync的应用
官方链接 https://cn.vuejs.org/v2/guide/components-custom-events.html#sync-修饰符 这个解释有点不太直观,用代码解释一下 父组件 v-b ...
- Filebeat 收集K8S 日志,生产环境实践
根据生产环境要求,需要采集K8Spod 日志,和开发协商之后,pod中应用会将日志输出到容器终端上,这时可以直接用filebeat 采集node节点上面的/var/log/containers/*.l ...
- golang 数据类型/基础语法
常量 变量 复合类型 结构体 数组 基础类型 整型 浮点型 复数 bool 值 字符型 字符串 错误(稍微有异议) 引用类型 切片 指针 字典 管道 函数 接口 其他语法结构 包 流程控制 运算符 注 ...
- [C/C++]快速读入代码(快读)
快读 1.为什么要有快读 好吧,有些题目看上去十分简单,例如https://www.luogu.com.cn/problem/P4305这道题,实际上数据量巨多,光是一个测试点就可能有几个MB,在这种 ...
- Golang Gtk+3教程:Grid布局
在上个例子中我们使用了box布局,现在让我们来学习另一种布局--grid.其实这几种布局都大同小异,如果你看懂了上一个例子,想必使用grid也不是难事. 程序运行效果: package main im ...
- 【笔记】springCloud--Alibaba--nacos介绍----启动报错解决方案
Nacos介绍 · 欢迎来到 Nacos 的世界! · Nacos 致力于帮助您发现.配置和管理微服务.Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现.服务配置.服务元数据及流量管 ...
- Jmeter系列(51)- 详解 Transaction Controller 事务控制器
如果你想从头学习Jmeter,可以看看这个系列的文章哦 https://www.cnblogs.com/poloyy/category/1746599.html 简单介绍 可以添加多个取样器(samp ...
- getting session bus failed: //bin/dbus-launch terminated abnormally with the following error: Autolaunch error: X11 initialization failed.
今天在调试dbus程序的时候,运行程序出现了getting session bus failed: //bin/dbus-launch terminated abnormally with the f ...
- Hyperledger Fabric 手动搭建【区块链学习三】
Hyperledger Fabric 手动搭建 前面我们学习了区块链是什么.还有自动搭建学习东西我们就要从简单到深入(入门到放弃),现在自动部署已经跑通了接下来就是手动搭建Fabric 网络可以更好的 ...
- oracle创建用户操作
打开命令提示框输入以下内容 1.输入:sqlplus /nolog //进入oralce控制台2.输入:conn /as sysdba //以管理员权限登录3.输入:create user abc i ...