暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Spring Boot 集成 Seata AT

TechStyle 2021-02-06
1003

什么是Seata?

一个可用于微服务架构的高性能且易于使用的分布式事务解决方案。


微服务中的分布式事务问题

一个典型的业务场景,电商下订单,减库存,扣余额的场景;当业务量较小的时候,我们通常会使用单机服务,使用单个本地数据源,拆分成3个子模块(订单模块,库存模块,账户模块),使用DB的本地事务来保证数据的一致性。


一旦业务量上来后,系统整体的吞吐和RT相对就会变慢,势必会影响用户体验。解决办法就是对单机服务进行服务拆分,将原先的3个子模块设计成基于3个不同数据源的3个服务(订单服务,库存服务,账户服务)。各自DB的本地事务可以保证每个事务的数据一致性。但是无法保证整个业务逻辑范围的数据一致性。


Seata解决方案


什么是分布式事务?

分布式事务是由一批分支事务组成的全局事务,通常分支事务只是本地事务。


Seata 的三个基本组件

  • TC (Transaction Coordinator) - 事务协调者:维护全局和分支事务的状态,驱动全局事务提交或回滚。

  • TM (Transaction Manager) - 事务管理器:定义全局事务的范围:开始全局事务、提交或回滚全局事务。

  • RM (Resource Manager) - 资源管理器:管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。


Seata管理的分布式事务的生命周期

  1. TM 要求 TC 开始新的全局事务。TC 生成代表全局事务的 XID。

  2. XID 通过微服务的调用链传播。

  3. RM 将本地事务注册为 XID 到 TC 的相应全局事务的分支。

  4. TM 要求 TC 提交或回退相应的 XID 全局事务。

  5. TC 驱动 XID 的相应全局事务下的所有分支事务,以完成分支提交或回滚。


快速集成 Seata  

环境准备

MySQL DB搭建

https://github.com/seata/seata-samples/blob/master/springboot-mybatis/sql/all_in_one.sql


Seata Server启动

# 拉取镜像
docker pull seataio/seata-server
# 启动容器
docker run --name seata-server -p 8091:8091 -e SEATA_IP=127.0.0.1 seataio/seata-server


服务介绍

服务
地址说明
seata-common
N/A
服务依赖
seata-storage127.0.0.1:8089
库存服务
seata-business127.0.0.1:8086
主体服务
seata-order
127.0.0.1:8088订单服务
seata-account
127.0.0.1:8087账户服务
seata-server
127.0.0.1:8091Seata Server


seata-common

Project Directory

核心 Maven Dependency

<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
<version>1.4.1</version>
</dependency>


seata-storage

Project Directory

applicaton.properties

spring.application.name=seata-storage
server.port=8089
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/db_storage?useSSL=false&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=123456
mybatis.mapper-locations=classpath:mapper/**/*.xml
seata.tx-service-group=my_test_tx_group
seata.service.grouplist.default=127.0.0.1:8091
logging.level.io.seata=info


seata-business

project directory

application.properties

spring.application.name=seata-business
server.port=8086
seata.service.grouplist.default=127.0.0.1:8091
seata.tx-service-group=my_test_tx_group
logging.level.io.seata=info


seata-order

project directory

application.properties

spring.application.name=seata-order
server.port=8088
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/db_order?useSSL=false&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=123456
mybatis.mapper-locations=classpath:mapper/**/*.xml
seata.tx-service-group=my_test_tx_group
seata.service.grouplist.default=127.0.0.1:8091
logging.level.io.seata=info


seata-account

project directory

application.properties

spring.application.name=seata-account
server.port=8087
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/db_account?useSSL=false&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=123456
mybatis.mapper-locations=classpath:mapper/**/*.xml
seata.tx-service-group=my_test_tx_group
seata.service.grouplist.default=127.0.0.1:8091
logging.level.io.seata=info


核心业务逻辑

使用 @GlobalTransactional 注解 管理全局事务,生成全局事务XID

查看DefaultGlobalTransaction#begin可以看到生成全局事务XID的细节

使用拦截器跨服务传递全局事务XID

使用过滤器绑定全局事务XID


Test

分别启动4个服务

测试成功场景

curl -v http://localhost:8086/api/business/purchase/commit

结果返回为true,订单表新增了一条记录,库存表扣减了库存,账户表扣减了金额。

测试失败场景

curl -v http://localhost:8086/api/business/purchase/rollback

结果返回为false,账户服务会抛出异常,全局事务会回滚,订单表不会新增记录,库存表不会扣减库存,账户表不会扣减余额。


Reference

https://github.com/seata/seata

https://github.com/seata/seata-samples

http://seata.io/zh-cn/docs/overview/what-is-seata.html

https://hub.docker.com/r/seataio/seata-server



泰克风格 只讲干货 不弄玄虚

文章转载自TechStyle,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论