1. 程式人生 > 程式設計 >Spring Cloud同步場景分散式事務怎樣做?試試Seata

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. 下載最新版本並解壓

github.com/seata/seata…

 

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下載地址

gitee.com/zlt2000/mic…

 

推薦閱讀

  掃碼關注有驚喜!

file