Spring Cloud同步場景分佈式事務怎樣作?試試Seata

file

1、概述

在微服務架構下,雖然咱們會盡可能避免分佈式事務,可是隻要業務複雜的狀況下這是一個繞不開的問題,如何保證業務數據一致性呢?本文主要介紹同步場景下使用SeataAT模式來解決一致性問題。java

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

 

2、Seata介紹

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

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

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

2.1. AT模式

該模式適合的場景:spring

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

file

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

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

 

2.2. MT模式

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

file

 

3、Seata場景樣例

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

file

3.1. 部署Seata的Server端

file

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

3.1.1. 下載最新版本並解壓

https://github.com/seata/seat...segmentfault

 

3.1.2. 修改 conf/registry.conf 配置

註冊中心和配置中心默認是file這裏改成nacos;設置 registryconfig 節點中的typenacos,修改serverAddr爲你的nacos節點地址。bash

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

  1. 事務失敗:扣除庫存成功 > 建立訂單成功 > 扣減帳戶餘額失敗,事務回滾

http://localhost:9090/placeOrderFallBack

 

3.4. demo下載地址

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

 

推薦閱讀

 
掃碼關注有驚喜!

file

相關文章
相關標籤/搜索