Spring Cloud同步場景分布式事務怎樣做?試試Seata


file

一、概述

在微服務架構下,雖然我們會盡量避免分布式事務,但是只要業務復雜的情況下這是一個繞不開的問題,如何保證業務數據一致性呢?本文主要介紹同步場景下使用SeataAT模式來解決一致性問題。

Seata阿里巴巴 開源的 一站式分布式事務解決方案 中間件,以 高效 並且對業務 0 侵入 的方式,解決 微服務 場景下面臨的分布式事務問題

 

二、Seata介紹

整體事務邏輯是基於 兩階段提交 的模型,核心概念包括以下3個角色:

  • TM:事務的發起者。用來告訴 TC,全局事務的開始,提交,回滾。
  • RM:具體的事務資源,每一個 RM 都會作為一個分支事務注冊在 TC。
  • TC:事務的協調者seata-server,用於接收我們的事務的注冊,提交和回滾。

目前的Seata有兩種模式可使用分別對應不同業務場景

2.1. AT模式

該模式適合的場景:

  • 基於支持本地 ACID 事務的關系型數據庫。
  • Java 應用,通過 JDBC 訪問數據庫。

file

 
一個典型的分布式事務過程:

  1. TMTC 申請開啟一個全局事務,全局事務創建成功並生成一個全局唯一的 XID
  2. XID 在微服務調用鏈路的上下文中傳播。
  3. RMTC 注冊分支事務,將其納入 XID 對應全局事務的管轄。
  4. TMTC 發起針對 XID 的全局提交或回滾決議。
  5. TC 調度 XID 下管轄的全部分支事務完成提交或回滾請求。

 

2.2. MT模式

該模式邏輯類似TCC,需要 自定義實現 preparecommitrollback的邏輯,適合 非關系型數據庫 的場景

file

 

三、Seata場景樣例

模擬一個簡單的用戶下單場景,4個子工程分別是 Bussiness(事務發起者)Order(創建訂單)Storage(扣減庫存)Account(扣減賬戶余額)

file

3.1. 部署Seata的Server端

file

Discover注冊、Config配置和Store存儲模塊默認都是使用file只能適用於單機,我們安裝的時候分別改成使用nacosMysql以支持server端集群

3.1.1. 下載最新版本並解壓

https://github.com/seata/seata/releases

 

3.1.2. 修改 conf/registry.conf 配置

注冊中心和配置中心默認是file這里改為nacos;設置 registryconfig 節點中的typenacos,修改serverAddr為你的nacos節點地址。

registry {
  type = "nacos"

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

config {
  type = "nacos"

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

 

3.1.3. 修改 conf/nacos-config.txt配置

file

  • 修改 service.vgroup_mapping 為自己應用對應的名稱;如果有多個服務,添加相應的配置

默認組名為${spring.application.name}-fescar-service-group,可通過spring.cloud.alibaba.seata.tx-service-group配置修改

  • 修改 store.modedb,並修改數據庫相關配置

 

3.1.4. 初始化seata的nacos配置

cd conf
sh nacos-config.sh 192.168.28.130

成功后在nacos的配置列表中能看到seata的相關配置

file

 

3.1.5. 初始化數據庫

執行conf/db_store.sql中的腳本

 

3.1.6. 啟動seata-server

sh bin/seata-server.sh -p 8091 -h 192.168.28.130

 

3.2. 應用配置

3.2.1. 初始化數據庫

執行腳本 seata-demo.sql

需在業務相關的數據庫中添加 undo_log 表,用於保存需要回滾的數據

 

3.2.2. 添加registry.conf配置

直接把 seata-server 中的registry.conf復制到每個服務中去即可,不需要修改
file

 

3.2.3. 修改配置

demo中的每個服務各自修改配置文件

  • bootstrap.yml 修改nacos地址
  • application.yml 修改數據庫配置

 

3.2.4. 配置數據源代理

Seata是通過代理數據源實現分布式事務,所以需要配置io.seata.rm.datasource.DataSourceProxyBean,且是@Primary默認的數據源,否則事務不會回滾,無法實現分布式事務

public class DataSourceProxyConfig {
    @Bean
    @ConfigurationProperties(prefix = "spring.datasource")
    public DruidDataSource druidDataSource() {
        return new DruidDataSource();
    }

    @Primary
    @Bean
    public DataSourceProxy dataSourceProxy(DruidDataSource druidDataSource) {
        return new DataSourceProxy(druidDataSource);
    }
}

因為使用了mybatis的starter所以需要排除DataSourceAutoConfiguration,不然會產生循環依賴

@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})

 

3.2.5. 事務發起者添加全局事務注解

事務發起者 business-service 添加 @GlobalTransactional 注解

@GlobalTransactional
public void placeOrder(String userId) {
    ......
}

 

3.3. 測試

提供兩個接口測試

  1. 事務成功:扣除庫存成功 > 創建訂單成功 > 扣減賬戶余額成功
    http://localhost:9090/placeOrder
  2. 事務失敗:扣除庫存成功 > 創建訂單成功 > 扣減賬戶余額失敗,事務回滾
    http://localhost:9090/placeOrderFallBack

 

3.4. demo下載地址

https://gitee.com/zlt2000/microservices-platform/tree/master/zlt-demo/seata-demo

 

推薦閱讀

 
掃碼關注有驚喜!

file


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM