分布式事务解决方案之Seata管理

2023-12-10 17:17:32 浏览数 (1)

前言

前面两篇文章,已经讲解什么是分布式事务,并且讲解了XA协议和TCC三段提交来解决分布式服务,其实这两种方式都是有缺点,要么比较古老,要么实现起来复杂度搞。那么有没有一个第三方框架,能够直接整合到现有项目,直接把本地事务改成全局分布式事务,类似我们使用Transation注解一样。本文就是讲解新的一种解决方案,也就是阿里提出的Seata。

Seata介绍及其原理

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

  1. AT模式主要关注多DB访问的数据一致性,当然也包括多服务下的多DB数据访问一致性问题。
  2. TCC模式主要关注业务拆分,在按照业务横向扩展资源时,解决微服务间调用的一致性问题。

在Seata分布式事务中,有两个重要的角色:TC(Transaction Coordinator)和TM(Transaction Manager)。TC负责维护全局和分支事务的状态,驱动全局事务提交或回滚。而TM则负责定义全局事务的范围:开始全局事务、提交或回滚全局事务。

其中,二阶段提交是Seata分布式事务的核心机制之一。在第一阶段,Seata会开启一个全局事务,并生成一个全局唯一的XID。然后,Seata会将这个XID通过RPC框架(如Dubbo、Spring Cloud等)传播到业务服务的各个参与者中,并开启相应的分支事务。这些参与者会根据自己的业务逻辑进行数据的修改,并记录相应的undo和redo日志。当所有参与者都执行完毕后,会向TC注册分支,并上报自己的状态。

在第二阶段,如果所有的分支都执行成功,TC会向所有的参与者发送全局提交的命令。否则,如果有任何一个分支执行失败,TC会向所有的参与者发送全局回滚的命令。在接收到全局提交或回滚的命令后,每个参与者会根据自己在第一阶段记录的undo和redo日志进行相应的数据恢复操作。

需要详细了解可以查看seata官网:https://seata.io/zh-cn/docs/overview/what-is-seata.html

Seata实践

代码整合需要注意的是0.7.0以下版本不支持mybatis批量插入,并且Seata适合分布式微服务开发,比较适合当下流行的SpringCloud全家桶。整合步骤:https://seata.io/zh-cn/docs/user/quickstart.html

1)每一个微服务必须创建undo_log

代码语言:sql复制
CREATE TABLE `undo_log` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `branch_id` bigint(20) NOT NULL,
  `xid` varchar(100) NOT NULL,
  `context` varchar(128) NOT NULL,
  `rollback_info` longblob NOT NULL,
  `log_status` int(11) NOT NULL,
  `log_created` datetime NOT NULL,
  `log_modified` datetime NOT NULL,
  `ext` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

2)安装事务协调器:seata-server:https://github.com/seata/seata/releases,下载服务器软件包,也就是Seata服务,将其解压缩。

3)整合sprngcloud

导入依赖spring-cloud-starter-alibaba-seata  导入seata-all-0.7.1,在去找到服务器软件包为seata-all-0.7.1

代码语言:text复制
<dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>

解压并启动seata-server,启动前需要修改Seata两个重要的配置文件

registry.conf:修改配置中心地址,注册中心配置 type = "nacos"

代码语言:text复制
  type = "nacos"

  nacos {
    serverAddr = "120.24.79.44"
    namespace = "public"
    cluster = "default"
  }

file.conf 事务日志存储 

所有想要用到分布式事务的微服务使用seata  DataSourceProxy代理自己的数据源,并修改service指定,用注册nacos的微服务名称

代码语言:text复制
store {
  ## store mode: file、db
  mode = "db"

  ## file store
  file {
    dir = "sessionStore"

    # branch session size , if exceeded first try compress lockkey, still exceeded throws exceptions
    max-branch-session-size = 16384
    # globe session size , if exceeded throws exceptions
    max-global-session-size = 512
    # file buffer size , if exceeded allocate new buffer
    file-write-buffer-cache-size = 16384
    # when recover batch read size
    session.reload.read_size = 100
    # async, sync
    flush-disk-mode = async
  }

  ## database store
  db {
    ## the implement of javax.sql.DataSource, such as DruidDataSource(druid)/BasicDataSource(dbcp) etc.
    datasource = "dbcp"
    ## mysql/oracle/h2/oceanbase etc.
    db-type = "mysql"
    url = "jdbc:mysql://127.0.0.1:3306/seata"
    user = "mysql"
    password = "mysql"
    min-conn = 1
    max-conn = 3
    global.table = "global_table"
    branch.table = "branch_table"
    lock-table = "lock_table"
    query-limit = 100
  }
}

代码语言:javascript复制
service {
  #vgroup->rgroup
  vgroup_mapping.微服务名称-fescar-service-group = "default"
  #only support single node
  default.grouplist = "127.0.0.1:8091"
  #degrade current not support
  enableDegrade = false
  #disable
  disable = false
  #unit ms,s,m,h,d represents milliseconds, seconds, minutes, hours, days, default permanent
  max.commit.retry.timeout = "-1"
  max.rollback.retry.timeout = "-1"
}

在原有项目的每个微服务,到拷贝这个两个配置文件到源文件目录中

        registry.conf

        file.conf 

启动测试分布式事务

给分布式大事务入口标注 @GlobalTransactional

代码语言:text复制

    @GlobalTransactional
    public void purchase(String userId, String commodityCode, int orderCount) {
        ......
    }

每个服务小事务管理加 @Transactional

Seata优缺点

Seata是一款优秀的分布式事务解决方案,具有简单易用、高性能、可扩展性和安全性等优点,但也存在一些缺点,如依赖数据库锁、难以管理和缺乏灵活性。

优点:

  1. 简单易用:Seata提供了丰富的客户端API和文档,使得用户可以很容易地开始使用和管理分布式事务。
  2. 高性能:Seata的分布式事务解决方案基于两阶段提交协议,具有高性能的特点。
  3. 可扩展性:Seata支持多种数据源和数据库类型,并且可以轻松地与其他服务集成。
  4. 安全性:Seata提供了安全机制,例如数据加密和身份验证,以确保分布式事务的安全性。

缺点:

  1. 依赖数据库锁:Seata的分布式事务解决方案依赖于数据库锁,可能会对数据库的性能产生影响,也就是去全局锁。
  2. 难以管理:随着业务的发展,分布式事务的数量和管理难度可能会增加,Seata需要用户手动管理和维护这些事务。
  3. 缺乏灵活性:Seata的分布式事务解决方案是基于两阶段提交协议的,这可能会限制用户的灵活性和可扩展性。

我正在参与2023腾讯技术创作特训营第四期有奖征文,快来和我瓜分大奖!

0 人点赞