Spring Cloud同步场景分布式事务怎样做?试试Seata
一、概述
在微服务架构下,虽然我们会尽量避免分布式事务,但是只要业务复杂的情况下这是一个绕不开的问题,如何保证业务数据一致性呢?本文主要介绍同步场景下使用Seata
的AT模式
来解决一致性问题。
Seata
是 阿里巴巴 开源的 一站式分布式事务解决方案 中间件,以 高效 并且对业务 0 侵入 的方式,解决 微服务 场景下面临的分布式事务问题
二、Seata介绍
整体事务逻辑是基于 两阶段提交 的模型,核心概念包括以下3个角色:
- TM:事务的发起者。用来告诉 TC,全局事务的开始,提交,回滚。
- RM:具体的事务资源,每一个 RM 都会作为一个分支事务注册在 TC。
- TC:事务的协调者seata-server,用于接收我们的事务的注册,提交和回滚。
目前的Seata
有两种模式可使用分别对应不同业务场景
2.1. AT模式
该模式适合的场景:
- 基于支持本地
ACID
事务的关系型数据库。 - Java 应用,通过
JDBC
访问数据库。
一个典型的分布式事务过程:
TM
向TC
申请开启一个全局事务,全局事务创建成功并生成一个全局唯一的XID
。XID
在微服务调用链路的上下文中传播。RM
向TC
注册分支事务,将其纳入 XID 对应全局事务的管辖。TM
向TC
发起针对XID
的全局提交或回滚决议。TC
调度XID
下管辖的全部分支事务完成提交或回滚请求。
2.2. MT模式
该模式逻辑类似TCC
,需要 自定义实现 prepare
、commit
和rollback
的逻辑,适合 非关系型数据库 的场景
三、Seata场景样例
模拟一个简单的用户下单场景,4个子工程分别是 Bussiness(事务发起者)、Order(创建订单)、Storage(扣减库存) 和 Account(扣减账户余额)
3.1. 部署Seata的Server端
Discover
注册、Config
配置和Store
存储模块默认都是使用file
只能适用于单机,我们安装的时候分别改成使用nacos
和Mysql
以支持server端集群
3.1.1. 下载最新版本并解压
https://github.com/seata/seata/releases
3.1.2. 修改 conf/registry.conf 配置
注册中心和配置中心默认是file
这里改为nacos
;设置 registry 和 config 节点中的type
为nacos
,修改serverAddr
为你的nacos
节点地址。
registry {
type = "nacos"
nacos {
serverAddr = "192.168.28.130"
namespace = "public"
cluster = "default"
}
}
config {
type = "nacos"
nacos {
serverAddr = "192.168.28.130"
namespace = "public"
cluster = "default"
}
}
3.1.3. 修改 conf/nacos-config.txt配置
- 修改 service.vgroup_mapping 为自己应用对应的名称;如果有多个服务,添加相应的配置
默认组名为
${spring.application.name}-fescar-service-group
,可通过spring.cloud.alibaba.seata.tx-service-group
配置修改
- 修改 store.mode 为
db
,并修改数据库相关配置
3.1.4. 初始化seata的nacos配置
cd conf
sh nacos-config.sh 192.168.28.130
成功后在nacos
的配置列表中能看到seata
的相关配置
3.1.5. 初始化数据库
执行conf/db_store.sql
中的脚本
3.1.6. 启动seata-server
sh bin/seata-server.sh -p 8091 -h 192.168.28.130
3.2. 应用配置
3.2.1. 初始化数据库
执行脚本 seata-demo.sql
需在业务相关的数据库中添加 undo_log 表,用于保存需要回滚的数据
3.2.2. 添加registry.conf配置
直接把 seata-server 中的registry.conf
复制到每个服务中去即可,不需要修改
3.2.3. 修改配置
demo中的每个服务各自修改配置文件
- bootstrap.yml 修改nacos地址
- application.yml 修改数据库配置
3.2.4. 配置数据源代理
Seata
是通过代理数据源实现分布式事务,所以需要配置io.seata.rm.datasource.DataSourceProxy
的Bean
,且是@Primary
默认的数据源,否则事务不会回滚,无法实现分布式事务
public class DataSourceProxyConfig {
@Bean
@ConfigurationProperties(prefix = "spring.datasource")
public DruidDataSource druidDataSource() {
return new DruidDataSource();
}
@Primary
@Bean
public DataSourceProxy dataSourceProxy(DruidDataSource druidDataSource) {
return new DataSourceProxy(druidDataSource);
}
}
因为使用了mybatis的starter所以需要排除DataSourceAutoConfiguration
,不然会产生循环依赖
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
3.2.5. 事务发起者添加全局事务注解
事务发起者 business-service
添加 @GlobalTransactional
注解
@GlobalTransactional
public void placeOrder(String userId) {
......
}
3.3. 测试
提供两个接口测试
- 事务成功:扣除库存成功 > 创建订单成功 > 扣减账户余额成功
http://localhost:9090/placeOrder - 事务失败:扣除库存成功 > 创建订单成功 > 扣减账户余额失败,事务回滚
http://localhost:9090/placeOrderFallBack
3.4. demo下载地址
https://gitee.com/zlt2000/microservices-platform/tree/master/zlt-demo/seata-demo
推荐阅读
- 日志排查问题困难?分布式日志链路跟踪来帮你
- zuul集成Sentinel最新的网关流控组件
- 阿里注册中心Nacos生产部署方案
- Spring Boot自定义配置项在IDE里面实现自动提示
- Spring Cloud Zuul的动态路由怎样做?集成Nacos实现很简单
- Spring Cloud开发人员如何解决服务冲突和实例乱窜?
扫码关注有惊喜!
Spring Cloud同步场景分布式事务怎样做?试试Seata的更多相关文章
- Spring Cloud异步场景分布式事务怎样做?试试RocketMQ
一.背景 在微服务架构中,我们常常使用异步化的手段来提升系统的 吞吐量 和 解耦 上下游,而构建异步架构最常用的手段就是使用 消息队列(MQ),那异步架构怎样才能实现数据一致性呢?本文主要介绍如何使用 ...
- Spring Cloud Gateway的动态路由怎样做?集成Nacos实现很简单
一.说明 网关的核心概念就是路由配置和路由规则,而作为所有请求流量的入口,在实际生产环境中为了保证高可靠和高可用,是尽量要避免重启的,所以实现动态路由是非常有必要的:本文主要介绍 Spring Clo ...
- Spring Cloud第九篇 | 分布式服务跟踪Sleuth
本文是Spring Cloud专栏的第九篇文章,了解前八篇文章内容有助于更好的理解本文: Spring Cloud第一篇 | Spring Cloud前言及其常用组件介绍概览 Spring Cl ...
- 【Spring Cloud】Spring Cloud Config 实现分布式配置中心
Spring Cloud Config 实现分布式配置中心 一.分布式配置中心 分布式系统中,往往拥有大量的服务应用,而每个应用程序都需要有对应的配置文件来协助完成服务环境初始化.运行.因此生产了大量 ...
- Spring+JTA+Atomikos+mybatis分布式事务管理
我们平时的工作中用到的Spring事务管理是管理一个数据源的.但是如果对多个数据源进行事务管理该怎么办呢?我们可以用JTA和Atomikos结合Spring来实现一个分布式事务管理的功能.了解JTA可 ...
- Spring Cloud(九):分布式配置中心和消息总线
我们在Spring Cloud(七):使用SVN存储分布式配置中心文件和实现refresh中讲到,如果需要客户端获取到最新的配置信息需要执行refresh,我们可以利用webhook的机制每次提交代码 ...
- 事务隔离级别与传播机制,spring+mybatis+atomikos实现分布式事务管理
1.事务的定义:事务是指多个操作单元组成的合集,多个单元操作是整体不可分割的,要么都操作不成功,要么都成功.其必须遵循四个原则(ACID). 原子性(Atomicity):即事务是不可分割的最小工作单 ...
- Spring事务隔离级别与传播机制详解,spring+mybatis+atomikos实现分布式事务管理
原创说明:本文为本人原创作品,绝非他处转载,转账请注明出处 1.事务的定义:事务是指多个操作单元组成的合集,多个单元操作是整体不可分割的,要么都操作不成功,要么都成功.其必须遵循四个原则(ACID). ...
- 构建Spring Cloud微服务分布式云架构
大型企业分布式微服务云架构服务组件 实现模块化.微服务化.原子化.灰度发布.持续集成 commonservice zipkinSpring 日志收集工具包,封装了Dapper和log-based追踪以 ...
随机推荐
- js五子棋游戏代码分享
HTML代码 <canvas id="game"></canvas> CSS代码 * { margin: 0; padding: 0; } #game { ...
- 洛谷 P1903 [国家集训队]数颜色
题意简述 给定一个数列,支持两个操作 1.询问l~r有多少不同数字 2.修改某个数字 题解思路 带修莫队 如果修改多了,撤销修改 如果修改少了,进行修改 代码 #include <cmath&g ...
- 004——Netty之高性能IO(Reactor)
一.原始方式 方法一: # 使用while循环,不断监听端口是否有新的套接字链接 while(true){ socket = accept(); handle(socket) } # 做法局限:处理效 ...
- Android lifecycle 使用详解
版权声明:本文为博主原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/gdutxiaoxu/article/det ...
- Yii的srbac拓展中“用户已经获授权项”无法查看
Yii的srbac拓展中“用户已经获授权项”点下拉框,选择一个有权限的用户时,根本无法列出权限. 原因是srbac把数据库的表中的ID默认为数字,像 123这样,但如果不是数字像这样 'y0f22ff ...
- Container及其内部进程监控剖析
目前市场上的虚拟化技术种类很多,例如moby(docker).LXC.RKT等等.在带来方便应用部署和资源充分利用的好处的同时,如何监控相应Container及其内部应用进程成为运维人员不可避免遇到的 ...
- 谈自由,ASP.NET Core才是未来?
首先我要说一下自己对自由的理解: 自由是我可以选择不干什么,但我要保留我可以干什么的可能性. 比如说我现在只有一个码农的角色,但我仍然要保留我可以扮演其他角色的可能, 比如成为一个作者,当我写下文章的 ...
- 线上ZK问题排查
问题描述 测试环境ZK集群的三个节点中zk1状态虽然是follower,启动也能正常启动(通过telnet也能telnet 2181端口); 无法通过zk客户端去连接2181端口,状态一致是CONNE ...
- 深入浅出TypeScript(2)- 用TypeScript创建web项目
前言 在第一篇中,我们简单介绍了TypeScript的一些简单语法,那么如果我们只是简单使用TypeScript开发一个web项目,应该做哪些准备?接下来我们就结合TypeScript和Webpack ...
- python基础知识补充
set 集合 {} 无序 集合天然去重 增 : s.add s.update 迭代添加 删 : s.pop( ) 随机删除 返回删除值 s.clear( ) 清空 获取到的是 set( ) del s ...