Spring Cloud Alibaba-(5)Seata【分布式事务】

Spring Cloud Alibaba-(1)搭建项目环境

Spring Cloud Alibaba-(2)Nacos【服务注册与发现、配置管理】

Spring Cloud Alibaba-(3)OpenFeign【服务调用】

Spring Cloud Alibaba-(4)Sentinel【流控和降级】

Spring Cloud Alibaba-(5)Seata【分布式事务】

Spring Cloud Alibaba-(6)Spring Cloud Gateway【网关】

Spring Cloud Alibaba-(7)RocketMQ【分布式消息队列】

【已解决】使用Seata分布式事务,服务端报错 could not find any implementation for class

注意

1.Seata 官网(https://seata.apache.org/zh-cn/

2.TC(事务协调者)、TM(事务管理器)、RM(资源管理器)

31c65c9f2397418e98c9e9027dd99626.png

3.Seata 工作流程

3.1 全局事务开启

(1)TM(事务管理器) 向 TC(事务协调者) 发起全局事务的开启请求。

(2)TC 生成一个全局唯一的 XID(全局事务 ID),并返回给 TM。

(3)XID 会通过 RPC 调用传递到所有参与事务的微服务中。

3.2 分支事务执行

(1)每个微服务在执行本地事务时,会向 TC 注册分支事务,并将 XID 与本地事务关联。

(2)Seata 的 RM(资源管理器) 会拦截 SQL 执行,生成 undo log(用于回滚的数据快照),并将数据和 undo log 一起提交到本地数据库。

(3)本地事务提交后,分支事务的状态为 “已提交但未完成”,等待全局事务的最终提交或回滚。

3.3 全局事务提交或回滚

(1)TM 向 TC 发起全局事务的提交或回滚请求。

(2)TC 根据所有分支事务的执行情况决定全局事务的最终状态:如果所有分支事务都成功,TC 通知所有 RM 提交分支事务。如果有任何一个分支事务失败,TC 通知所有 RM 根据 undo log 回滚所有分支事务。

eg. 案例

假设有两个微服务 A 和 B,分别对应事务 A 和事务 B:

  1. 事务 A 提交成功:

    • 事务 A 的本地事务提交成功,生成了 undo log。

    • 事务 A 的状态为 “已提交但未完成”,等待全局事务的最终确认。

  2. 事务 B 提交失败:

    • 事务 B 的本地事务提交失败,向 TC 报告失败状态。

    • TC 检测到事务 B 失败,决定回滚全局事务。

  3. 全局事务回滚:

    • TC 通知事务 A 的 RM 回滚事务 A。

    • RM 根据事务 A 的 undo log 执行回滚操作,将数据恢复到事务开始前的状态。

    • 事务 B 由于已经失败,无需额外操作。

4.Seata 提供的分布式事务模式

4.1 AT 模式(Automatic Transaction)

(1)特点:

        自动补偿:Seata 自动生成反向 SQL(undo log)来实现回滚。

        对业务代码无侵入:开发者只需使用 @GlobalTransactional 注解即可。

        基于两阶段提交(2PC)。

(2)适用场景:适合大多数业务场景,尤其是对业务代码侵入性要求低的场景

(3)工作流程:

  1. 阶段一:

    • 每个分支事务执行本地事务,并生成 undo log。

    • 本地事务提交,但全局事务未完成。

  2. 阶段二:

    • 如果所有分支事务成功,TC 通知 RM 删除 undo log。

    • 如果有分支事务失败,TC 通知 RM 根据 undo log 回滚数据。

4.2 TCC 模式(Try-Confirm-Cancel)

(1)特点:

        手动补偿:开发者需要实现 Try、Confirm 和 Cancel 三个方法。

        高性能:避免了全局锁,适合高并发场景。

        强一致性。

(2)适用场景:适合对性能要求高、业务逻辑复杂的场景,如金融、电商等。

(3)工作流程

  1. Try 阶段:尝试执行业务逻辑,预留资源(如冻结库存)。

  2. Confirm 阶段:如果所有分支事务成功,提交资源(如扣减库存)。

  3. Cancel 阶段:如果有分支事务失败,释放资源(如解冻库存)。

5.下载(Seata-Server版本历史 | Apache Seata

166fb3d70fe74951bce65b48c729842c.png

6.db + nacos 高可用模式启动 Seata 服务端

6.1 创建seata_server数据库,导入mysql.sql

8ab221b6b52e4d7097bb8b656e34767b.png

6.2 修改seata配置文件,使用 db+nacos 高可用模式(将application.example.yml 关于nacos、store.db配置复制过来)

98482c9886b946d28a2eb785d805e0d2.png

#  Copyright 1999-2019 Seata.io Group.
#
#  Licensed under the Apache License, Version 2.0 (the "License");
#  you may not use this file except in compliance with the License.
#  You may obtain a copy of the License at
#
#  http://www.apache.org/licenses/LICENSE-2.0
#
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS,
#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#  See the License for the specific language governing permissions and
#  limitations under the License.

server:
  port: 7091

spring:
  application:
    name: seata-server

logging:
  config: classpath:logback-spring.xml
  file:
    path: ${user.home}/logs/seata
  extend:
    logstash-appender:
      destination: 127.0.0.1:4560
    kafka-appender:
      bootstrap-servers: 127.0.0.1:9092
      topic: logback_to_logstash

console:
  user:
    username: seata
    password: seata
seata:
  config:
    # support: nacos 、 consul 、 apollo 、 zk  、 etcd3
    type: nacos
    nacos:
      server-addr: 127.0.0.1:8848
      namespace:
      group: SEATA_GROUP
      username:
      password:
      context-path:
      ##if use MSE Nacos with auth, mutex with username/password attribute
      #access-key:
      #secret-key:
      data-id: seataServer.properties
  registry:
    # support: nacos, eureka, redis, zk, consul, etcd3, sofa
    type: nacos
    nacos:
      application: seata-server
      server-addr: 127.0.0.1:8848
      group: SEATA_GROUP
      namespace:
      cluster: default
      username:
      password:
      context-path:
      ##if use MSE Nacos with auth, mutex with username/password attribute
      #access-key:
      #secret-key:
  store:
    # support: file 、 db 、 redis 、 raft
    mode: db
    session:
      mode: db
    lock:
      mode: db
    db:
      datasource: druid
      db-type: mysql
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://127.0.0.1:3306/seata_server?rewriteBatchedStatements=true&useSSL=false
      user: ***
      password: ***
      min-conn: 10
      max-conn: 100
      global-table: global_table
      branch-table: branch_table
      lock-table: lock_table
      distributed-lock-table: distributed_lock
      query-limit: 1000
      max-wait: 5000
#  server:
#    service-port: 8091 #If not configured, the default is '${server.port} + 1000'
  security:
    secretKey: SeataSecretKey0c382ef121d778043159209298fd40bf3850a017
    tokenValidityInMilliseconds: 1800000
    ignore:
      urls: /,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.jpeg,/**/*.ico,/api/v1/auth/login

6.3 修改配置中心配置

0f584a4164684203a3c836f6372ac10d.png

66000d1c67904106b0edcc41e5b26bb5.png

e6101d2092fb476785881892b2824f6b.png

6.4 将配置注册到Nacos

32000dedbdf142f69030037ac3bb1fff.png

6.5 双击启动 Seata 服务

f4cc3f9b8785406995861b9fe7c6bf23.png

6.6 访问 http://localhost:7091/

76d43a8d56ad4369af2cb185824e4175.png

7.项目搭建 Seata 客户端

7.1 涉及Seata分布式事务的服务(订单服务、产品服务),添加Maven依赖

<!-- seata 分布式事务 -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>

7.2 涉及Seata分布式事务的服务(订单服务、产品服务),数据库都需要添加undo_log表

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;

7.3 涉及Seata分布式事务的服务(订单服务、产品服务),bootstrap.yml 配置 Seata

7.3.1 订单服务 bootstrap.yml 配置 Seata

server:
  port: 8000

spring:
  profiles:
    active: public
  application:
    name: order-service
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/springcloud2024
    username: root
    password: 123456
  cloud:
    nacos:
      discovery:
        server-addr: http://localhost:8848
      config:
        server-addr: http://localhost:8848
        file-extension: yaml
        namespace: public
        shared-configs:
          - data-id: order-service-default.yaml
            refresh: true
          - data-id: order-service-default-test.yaml
            refresh: true
    openfeign:
      httpclient:
        # 连接超时
        connection-timeout: 5000
    sentinel:
      transport:
        dashboard: http://localhost:8858
      datasource:
        flow-rule:
          nacos:
            server-addr: http://localhost:8848
            data-id: order-service-flow-rule
            rule-type: flow

# Openfeign 整合 sentinel
feign:
  sentinel:
    enabled: true

seata:
  registry:
    type: nacos
    nacos:
      server-addr: http://localhost:8848
      application: seata-server
      group: SEATA_GROUP
  config:
    type: nacos
    nacos:
      server-addr: http://localhost:8848
      group: SEATA_GROUP
  tx-service-group: default_tx_group

7.3.2 产品服务 bootstrap.yml 配置 Seata

server:
  port: 8400

spring:
  application:
    name: product-service
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/springcloud2024
    username: root
    password: 123456
  cloud:
    nacos:
      discovery:
        server-addr: http://localhost:8848
      config:
        server-addr: http://localhost:8848

seata:
  registry:
    type: nacos
    nacos:
      server-addr: http://localhost:8848
      application: seata-server
      group: SEATA_GROUP
  config:
    type: nacos
    nacos:
      server-addr: http://localhost:8848
      group: SEATA_GROUP
  tx-service-group: default_tx_group

7.4 业务方法加 @GlobalTransactional 开启分布式任务

cda3415837d94b18b1c5729d8aef758b.png

7.5 订单服务调用下单接口。下单失败,订单服务没有新增订单,产品服务没有扣减库存,实现分布式任务。

98fa434b055141d487fc96e52f17ff32.png

af9ce66e1b7844e991f7486bdf19fe95.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值