Seata分布式事务

文章目录

  • 一、为什么要用Seata
    • 1.问题背景
    • 2.数据不一致的原因
  • 二、Seata简介
    • Seata原理和设计
    • 协议分布式事务处理过程的三个组件
    • 一个典型的分布式事务过程
    • Seata可靠吗
  • 三、springcloud+eureka+seata实现分布式事务处理
    • 演示项目组成结构
    • 搭建步骤
      • 配置Seata-server
        • 搭建Eureka
        • 创建seata-server数据库
        • 配置seata-server
        • 配置搭建分布式事务
        • 实例演示

一、为什么要用Seata

1.问题背景

在微服务的架构下,数据不一致

2.数据不一致的原因

在微服务的环境下,由于调用链路跨越多个应用,甚至跨越多个数据源,数据的一致性在普通情况下难以保证,导致数据不一致的原因非常多,这里列举了三个最常见的原因

1.业务异常一个服务链路调用中,如果调用的过程出现业务异常,产生异常的应用独立回滚,非异常的应用数据已经持久化到数据库。
2.网络异常调用的过程中,由于网络不稳定,导致链路中断,部分应用业务执行完成,部分应用业务未被执行。
3.服务不可用若服务不可用,无法被正常调用,也会导致问题的产生

在以往如果出现数据不一致的问题,相信大多数的解决方案是这样的

1.人工补偿数据
2.定时任务检查和补偿数据
但是这两种方式的缺点也是显然意见的,一种是浪费大量的人力成本和时间,另外一种是浪费大量的系统资源去检查数据是否一致和额外的人力成本。

二、Seata简介

Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式,为用户打造一站式的分布式解决方案。

Seata原理和设计

我们可以把一个分布式事务理解成一个包含了若干分支事务的全局事务,全局事务的职责是协调其下管辖的分支事务达成一致,要么一起成功提交,要么一起失败回滚。此外,通常分支事务本身就是一个满足ACID的本地事务。这是我们对分布式事务结构的基本认识,与 XA 是一致的。

协议分布式事务处理过程的三个组件

  1. Transaction Coordinator (TC): 事务协调器,维护全局事务的运行状态,负责协调并驱动全局事务的提交或回滚;
  2. Transaction Manager ™: 控制全局事务的边界,负责开启一个全局事务,并最终发起全局提交或全局回滚的决议;
  3. Resource Manager (RM):控制分支事务,负责分支注册、状态汇报,并接收事务协调器的指令,驱动分支(本地)事务的提交和回滚。

一个典型的分布式事务过程

  1. TM 向 TC 申请开启一个全局事务,全局事务创建成功并生成一个全局唯一的 XID;

  2. XID 在微服务调用链路的上下文中传播; RM 向 TC 注册分支事务,将其纳入 XID 对应全局事务的管辖; TM 向 TC 发起针对

  3. XID 的全局提交或回滚决议; TC 调度 XID 下管辖的全部分支事务完成提交或回滚请求。

Seata可靠吗

一项新的技术出来不是可以直接运用,需要市场的检验,观察他是否被别的企业运用到生产环境,是否真的可靠
图片不是很全,可以去seata官网查看更多合作企业
Seata官网

可以看出很多知名企业都使用Seata,让我们一起来看看seata在springcloud项目中是如何使用的。

三、springcloud+eureka+seata实现分布式事务处理


演示项目组成结构

搭建步骤

配置Seata-server

搭建Eureka

Spring Cloud教程 | 第一篇:服务的注册与发现 | Eureka
可以参照上述文章进行配置Eureka,然后对application.yml进行端口号修改

我们更改下端口号为6001

创建seata-server数据库

-- -------------------------------- The script used when storeMode is 'db' --------------------------------
-- the table to store GlobalSession data
CREATE TABLE IF NOT EXISTS `global_table`
(`xid`                       VARCHAR(128) NOT NULL,`transaction_id`            BIGINT,`status`                    TINYINT      NOT NULL,`application_id`            VARCHAR(32),`transaction_service_group` VARCHAR(32),`transaction_name`          VARCHAR(128),`timeout`                   INT,`begin_time`                BIGINT,`application_data`          VARCHAR(2000),`gmt_create`                DATETIME,`gmt_modified`              DATETIME,PRIMARY KEY (`xid`),KEY `idx_gmt_modified_status` (`gmt_modified`, `status`),KEY `idx_transaction_id` (`transaction_id`)
) ENGINE = InnoDBDEFAULT CHARSET = utf8;-- the table to store BranchSession data
CREATE TABLE IF NOT EXISTS `branch_table`
(`branch_id`         BIGINT       NOT NULL,`xid`               VARCHAR(128) NOT NULL,`transaction_id`    BIGINT,`resource_group_id` VARCHAR(32),`resource_id`       VARCHAR(256),`branch_type`       VARCHAR(8),`status`            TINYINT,`client_id`         VARCHAR(64),`application_data`  VARCHAR(2000),`gmt_create`        DATETIME(6),`gmt_modified`      DATETIME(6),PRIMARY KEY (`branch_id`),KEY `idx_xid` (`xid`)
) ENGINE = InnoDBDEFAULT CHARSET = utf8;-- the table to store lock data
CREATE TABLE IF NOT EXISTS `lock_table`
(`row_key`        VARCHAR(128) NOT NULL,`xid`            VARCHAR(128),`transaction_id` BIGINT,`branch_id`      BIGINT       NOT NULL,`resource_id`    VARCHAR(256),`table_name`     VARCHAR(32),`pk`             VARCHAR(36),`gmt_create`     DATETIME,`gmt_modified`   DATETIME,PRIMARY KEY (`row_key`),KEY `idx_branch_id` (`branch_id`)
) ENGINE = InnoDBDEFAULT CHARSET = utf8;

配置seata-server

从官网下载seata-server,这里下载的是seata-server-1.4.2.zip,下载地址:https://github.com/seata/seata/releases
解压seata-server安装包到指定目录,接着我们修改conf目录下的file.conf
配置文件,主要修改自定义事务组名称,事务日志存储模式为db及数据库连接信息;
把mode形式改为db:

之后在file.conf设置数据库等信息,主要设置数据库链接,账户名和密码

## database store propertydb {## the implement of javax.sql.DataSource, such as DruidDataSource(druid)/BasicDataSource(dbcp)/HikariDataSource(hikari) etc.datasource = "druid"## mysql/oracle/postgresql/h2/oceanbase etc.dbType = "mysql"driverClassName = "com.mysql.cj.jdbc.Driver"## if using mysql to store the data, recommend add rewriteBatchedStatements=true in jdbc connection paramurl = "jdbc:mysql://127.0.0.1:3306/seata-server?serverTimezone=UTC"user = "root"password = "123456"minConn = 5maxConn = 100globalTable = "global_table"branchTable = "branch_table"lockTable = "lock_table"queryLimit = 100maxWait = 5000}

然后进入conf下面的registry.conf文件,修改注册中心为eureka如图:

现在我们启动eureka-server

并启动seata-server:
双击\seata-server-1.4.2\bin\seata-server.bat

我们访问Eureka服务http://localhost:6001
能看到seata-server已经注册到eureka:

配置搭建分布式事务

其实就是不同的Client,具体如何搭建可参考Spring Cloud教程 | 第一篇:服务的注册与发现 | Eureka:四、创建Client
Maven依赖
pom.xml添加如下:

<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-seata</artifactId>
</dependency>

application.properties
配置文件中添加如下

logging.level.io.seata=info
spring.cloud.alibaba.seata.tx-service-group=my_test_tx_group

在了解怎么配置之后
我们下载并打开演示用的例子https://gitee.com/lin_qichun/seata.git

springCloud-eureka-seata文件
并修改account,order,storage,bussiness里application.properties文件,file.conf,registry.conf文件

application.properties文件:

spring.application.name=storage-service
server.port=8081
spring.datasource.url=jdbc:mysql://rm-2zetd9474ydd1g5955o.mysql.rds.aliyuncs.com:3306/fescar?useSSL=false&serverTimezone=UTC
spring.datasource.username=workshop
spring.datasource.password=Workshop123
spring.cloud.alibaba.seata.tx-service-group=my_test_tx_group
logging.level.org.springframework.cloud.alibaba.seata.web=debug
logging.level.io.seata=info
eureka.instance.hostname=127.0.0.1
eureka.instance.prefer-ip-address=true
eureka.client.serviceUrl.defaultZone=http://${eureka.instance.hostname}:6001/eureka/
feign.hystrix.enabled=true
spring.main.allow-bean-definition-overriding=true

以及file.conf文件,service里边配置的事务组应该跟服务名保持一致

修改file.conf文件中greouplist为seata-server服务器地址,如图:

修改registry.conf

在BusinessService里需要使用分布事务处理的地方加上 @GlobalTransactional注解,如:

实例演示

启动account,order,storage,bussiness这四个项目

在Navicat里连接远程数据库:
rm-2zetd9474ydd1g5955o.mysql.rds.aliyuncs.com
用户:workshop
密码:Workshop123

打开fescar

我们分别点开前三个表,可以观察到:
账户表U100000用户有10000

订单表则没有数据

库存表库存为100

我们使用postman发送一条请求http://localhost:8084/purchase/commit


得到全局事务提交反馈则表明成功

我们再去观察三个表:
账户表:钱少了3000

订单表:新增了一条记录

库存表:少了30库存

这时我们把库存改为比30小,或者钱数改为比3000小来模仿库存不足或者钱数不足的情况,我们这里用修改钱数举例

递交数据请求:

可看到执行回滚,观察3个表,数据都无改变

现在来模拟程序出错,看seata是否执行回滚

我们在AccountService里加上两行错误代码,账户程序在执行到此处时会报错,重启AccountApplication,同时我们将数据库里的钱修改大于3000,调用链接


可以看到报错,此时我们去观察数据库那3个表,发现数据没变,表明回滚成功


springcloud+eureka+seata实现分布式事务处理相关推荐

  1. springCloud整合seata实现分布式事务

    seata简介 Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务.Seata 将为用户提供了 AT.TCC.SAGA 和 XA 事务模式,为用户打造一站式的分布式 ...

  2. SpringCloud Alibaba Seata处理分布式事务-微服务(三十九)

    订单/库存/账户业务微服务准备 业务需求 下订单->减库存->扣余额->改(订单)状态 新建订单Order-Module seata-order-service2001 POM &l ...

  3. 分布式事务解决方案 - SpringCloud Alibaba Seata

    目录 github代码:GitHub - 18409489244/seata: 基于springcloud alibaba seata 的分布式事务demo 一.常见分布式事务解决方案 二.分布式事务 ...

  4. SpringCloud Alibaba实战--第八篇:Seata分布式事务处理

    系列文章目录 微服务新王SpringCloudAlibaba 文章目录 系列文章目录 前言 一.Seata简介 1. Seata是什么? 2. ID+三组件模型 3. 处理过程 二.Seata下载安装 ...

  5. Spring Cloud Eureka整合 Seata 实现分布式事务

    一.Seata 介绍 Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务.Seata 将为用户提供了 AT.TCC.SAGA 和 XA 事务模式,为用户打造一站式的 ...

  6. springCloud Alibaba seata 分布式事务

    事务是指一个操作单元,在这个操作单元中所有操作最终要保持一致的行为. 要么所有操作都成功,要么所有操作都被撤销. 本地事务:   分布式事务:  分布式事务场景 单体系统访问多个数据库 多个微服务访问 ...

  7. SpringCloud集成Seata精简入门教程

    seata注册到nacos,实现高可用 一枚路过的程序猿 https://www.jianshu.com/p/cf455eaa650a nacos下载 seata官网文档 seata下载 在Mysql ...

  8. SpringCloud 整合 Seata

    <分布式事务>https://blog.csdn.net/u011060911/article/details/122210788上面的文章系统介绍了分布式事务相关的理论知识,本文则通过代 ...

  9. Spring Cloud Alibaba系列四:集成 seata 实现分布式事务

    文章目录 Spring Cloud Alibaba系列四:集成 seata 实现分布式事务 前言 Seata 是什么? Seata 术语 安装 seata 1.创建 seata 数据库,并添加对应的表 ...

  10. 分布式事务处理技术之LCN

    分布式事务LCN 第一章 分布式事务介绍 一.什么是分布式事务 二.XA 的两阶段提交方案 三.TCC 解决方案 四.分布式事务中间件解决方案 第二章 LCN分布式事务处理框架介绍 一.什么是LCN ...

最新文章

  1. explain性能分析
  2. RCP开发小技巧(二)
  3. 2013年新的开始,每周至少要写一篇博客!
  4. STL 之remove,remove_if,remove_copy,remove_copy_if
  5. 一个表单同时向两个页面传值
  6. python2 print_Python2和Python3中print的不同点
  7. LeetCode 838. 推多米诺(模拟)
  8. 专访福建移动林志云: 5G使能,运营商全面进入数字化转型之路
  9. matlab中solver函数_Matlab中微分方程的模型
  10. 目前支持DDR3-1600(包括主板超频)最强的CPU是哪个?
  11. 百度地图与 select下拉框的双向维护
  12. 人工智能知识点思维导图,人工智能算法思维导图
  13. 发那科服务器显示021,发那科(FANUC)系统报警代码大全
  14. ets交易软件测试简历,ETS工具使用指南
  15. Windows10专业版系统“本地组策略编辑器”丢失解决方案
  16. 基于SQL求集合的交、并、补
  17. Android闹钟最终版【android源码闹钟解析】
  18. java-commen判断一个数据是否存在于列表中
  19. 2022数模国赛B题无人机第一题第一小问的简单编程
  20. 可由线性表示且表达式唯一_一个向量能由另一个向量组线性表示,且表示式唯一的等价条件是什么?...

热门文章

  1. C语言入门——printf(““)左对齐与右对齐问题
  2. 为什么技术管理者要懂一点产品思维?向苹果,爱马仕学习产品底层素养
  3. magic4升级鸿蒙系统,Magic UI 4.0将于9月中旬内测招募 后续可升鸿蒙系统
  4. 驻点的定义:(要求平滑)  y=|x|; 不存在驻点; 极值点的定义: 导数不存在的点也有可能是极值点 拐点: 一二阶导数等于零各是什么意义 倒代换
  5. spss导入Excel显示连接服务器超时,Excel里的日期在spss里怎么不正常显示
  6. oracle中那个日期怎么相减_oracle 日期相减
  7. html制作网页包涵视频和音频,HTML5 网页音频和视频( 和 )
  8. 本地微信公众号授权登录获取code步骤
  9. CAD.net 根据句柄获取图元
  10. STM32读写FPGA存储器EPCS器件(EPCS1、EPCS4)