三天学会阿里分布式事务框架Seata-应用seata AT模式方案解决分布式事务问题

锋哥原创的分布式事务框架Seata视频教程:

实战阿里分布式事务框架Seata视频教程(无废话,通俗易懂版)_哔哩哔哩_bilibili实战阿里分布式事务框架Seata视频教程(无废话,通俗易懂版)共计10条视频,包括:1 阿里分布式事务框架Seata简介、2 分布式事务简介、3 SpringCloud Alibaba分布式基础案例搭建等,UP主更多精彩视频,请关注UP账号。icon-default.png?t=N7T8https://www.bilibili.com/video/BV1Uf4y1579F/seata主推的是AT模式强一致性解决方案,所以我们采用这个方案来解决前面案例的分布式问题。

7.1 下载和运行seata server

seata server地址:Releases · apache/incubator-seata · GitHub

最新版本 v1.4.2

我们用windows演示,下载seata-server-1.4.2.zip

seata-server配置文件:

seata server所有的配置都在conf文件夹内,该文件夹内有两个文件我们必须要详细介绍下。 seata server默认使用file(文件方式)进行存储事务日志、事务运行信息,我们可以通过-m db脚本参数的形式来指定,目前仅支持file、db这两种方式。

file.conf

该文件用于配置存储方式、透传事务信息的NIO等信息,默认对应registry.conf文件内的file方式配置。

registry.conf

seata server核心配置文件,可以通过该文件配置服务注册方式、配置读取方式。

注册方式目前支持file 、nacos 、eureka、redis、zk、consul、etcd3、sofa等方式,默认为file,对应读取file.conf内的注册方式信息。

读取配置信息的方式支持file、nacos 、apollo、zk、consul、etcd3等方式,默认为file,对应读取file.conf文件内的配置。

file.conf我们加一个service配置:

service {
  #vgroup->rgroup 服务分组  集群分组默认为"default"
  vgroupMapping.my_test_tx_group = "default"
  #only support single node
  default.grouplist = "127.0.0.1:8091"
  #degrade current not support 服务降级达到多次错误不走seata
  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"
}

这里事务分组概念,我们最后单独讲,主要是为了集群故障的时候,能快速切换,实现高可用;

配置分组映射,集群分组再配置grouplist,暴露server地址,提供给seata-client调用;

最后我们运行bin目录下的seata-server.bat启动seata-server:

启动OK,监听端口8091

7.2 每个数据库都建一个undo_log回滚日志表

根据seata AT模式规范,我们新建undo_log表,db_account和db_order都要建;

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=3 DEFAULT CHARSET=utf8

7.3 项目里添加seata-client maven依赖

我们只需要在seata-common公共模块项目里添加seata依赖,其他子模块都有了,方便;

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

7.4 项目里配置seata分布式事务

首先是每个项目都要配置seata支持,请求seata-server,根据配置;

再通过@GlobalTransactional注解,开启全局分布式事务;

seata-order子项目 application.yml配置改下:

server:
  port: 8081
  servlet:
    context-path: /

spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/db_order?serverTimezone=Asia/Shanghai
    username: root
    password: 123456
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
    alibaba:
      seata:
        tx-service-group: my_test_tx_group
  application:
    name: seata-order

mybatis:
  mapper-locations: classpath:mybatis/mapper/*.xml


seata:
  service:
    vgroup-mapping:
      my_test_tx_group: default
    grouplist:
      default: 127.0.0.1:8091
    enable-degrade: false
    disable-global-transaction: false

主要多了服务分组和集群分组的配置:

同理,seata-account下的application.yml配置:

server:
  port: 8082
  servlet:
    context-path: /

spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/db_account?serverTimezone=Asia/Shanghai
    username: root
    password: 123456
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
    alibaba:
      seata:
        tx-service-group: my_test_tx_group
  application:
    name: seata-account

mybatis:
  mapper-locations: classpath:mybatis/mapper/*.xml

seata:
  service:
    vgroup-mapping:
      my_test_tx_group: default
    grouplist:
      default: 127.0.0.1:8091
    enable-degrade: false
    disable-global-transaction: false

seata-web下的application.yml配置:

server:
  port: 80
  servlet:
    context-path: /


spring:
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
    alibaba:
      seata:
        tx-service-group: my_test_tx_group
  application:
    name: seata-web

seata:
  service:
    vgroup-mapping:
      my_test_tx_group: default
    grouplist:
      java1234-seata-server: 127.0.0.1:8091
    enable-degrade: false
    disable-global-transaction: false

seata-web项目->WebController->shopping方法,添加@GlobalTransactional注解

7.5 分布式案例测试

三个子项目一起运行;

两个RM在seata-server注册成功;

seata-web项目的RM,TM注册成功;

seata-order项目的TM注册成功;

seata-account项目的TM注册成功;

我们用postman 发送 http://localhost/shopping post请求

执行发现,订单表,和日志表都没有数据,说明测试OK;

7.6 setata二阶段提交过程剖析

因为是执行是一瞬间的,很多小伙伴根本无法感受到内部的二阶段提交过程。

  • 一阶段:业务数据和回滚日志记录在同一个本地事务中提交,释放本地锁和连接资源。

  • 二阶段:

    • 提交异步化,非常快速地完成。

    • 回滚通过一阶段的回滚日志进行反向补偿。

所以我们在再seata-account项目里搞个断点,来看下回滚的一个流程;

seata-account项目debug启动;

再次postman测试,我们立刻查看db_order数据库表信息(比较难捕获,因为提交事务超时就立刻回滚,看不到信息)

订单服务执行完的时候,

db_order有数据

undo_log也有数据

说明一阶段业务数据和回滚日志记录在同一个本地事务中提交,释放本地锁和连接资源。

然后下面,如果提交事务超时或者有接口调用异常,则分支事务立刻根据回滚日志,立刻进行反向补偿,最后回滚日志会被清空;

如果接口调用一切正常,日志清空,全局事务提交,完成本次事务操作;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值