天天看點

開源分布式事務中間件Seata使用指南

介紹

Seata 是阿裡巴巴開源的分布式事務中間件,一種分布式事務解決方案,具有高性能和易于使用的微服務架構。

初衷

  • 對業務無侵入:即減少技術架構上的微服務化所帶來的分布式事務問題對業務的侵入
  • 高性能:減少分布式事務解決方案所帶來的性能消耗

分布式事務定義

分布式事務是一個全局事務,由一批分支事務組成,通常分支事務隻是本地事務。

開源分布式事務中間件Seata使用指南

設計

Seata中有兩種分布式事務實作方案,AT和TCC。

AT

AT模式是基于XA事務演進而來,核心是對業務無侵入,是一種改進後的兩階段送出,需要資料庫支援。

開源分布式事務中間件Seata使用指南

基本元件:

  • 事務協調器(TC):事務協調器,維護全局事務的運作狀态,負責協調并驅動全局事務的送出或復原。
  • Transaction Manager(TM): 控制全局事務的邊界,負責開啟一個全局事務,并最終發起全局送出或全局復原的決議。
  • 資料總管(RM):控制分支事務,負責分支注冊、狀态彙報,并接收事務協調器的指令,驅動分支(本地)事務的送出和復原。

處理流程:

  1. TM要求TC開始新的全局事務。TC生成表示全局事務的XID。
  2. XID通過微服務的調用鍊傳播。
  3. RM将本地事務注冊為XID到TC的相應全局事務的分支。
  4. TM要求TC送出或復原XID的相應全局事務。
  5. TC在XID的相應全局事務下驅動所有分支事務以完成分支送出或復原。
開源分布式事務中間件Seata使用指南

TCC

Seata要求每個接口實作prepare、commit、rollback。

與 AT 模式一樣,在運作時,該切面會攔截所有對 TCC 接口的調用。每調用一次 Try 接口,切面會先向 TC 注冊一個分支事務,然後才去執行原來的 RPC 調用。當請求鍊路調用完成後,TC 通過分支事務的資源 ID 回調到正确的參與者去執行對應 TCC 資源的 Confirm 或 Cancel 方法。

  1. 初步操作 Try:完成所有業務檢查,預留必須的業務資源。
  2. 确認操作 Confirm:真正執行的業務邏輯,不做任何業務檢查,隻使用 Try 階段預留的業務資源。是以,隻要 Try 操作成功,Confirm 必須能成功。另外,Confirm 操作需滿足幂等性,保證一筆分布式事務能且隻能成功一次。
  3. 取消操作 Cancel:釋放 Try 階段預留的業務資源。同樣的,Cancel 操作也需要滿足幂等性。

Seata Server安裝

1.下載下傳最新版本的 Seata Sever

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

2. 解壓并啟動 Seata server

unzip seata-server-xxx.zip
cd distribution
sh ./bin/seata-server.sh 8091 file           

示例

場景:

把資料庫zeroa中proxy表的一條資料轉移到資料庫zerob中proxy表裡面。

子產品:

zero-discovery-server:注冊中心

zero-gateway-server:服務網關

zero-consumer:服務消費者

zero-provider-a:服務提供者A

zero-provider-b:服務提供者B

架構及版本:

Spring-cloud:Finchley.BUILD-SNAPSHOT

spring-cloud-starter-netflix-eureka-server:2.0.4.BUILD-SNAPSHOT

spring-cloud-starter-netflix-eureka-client:2.0.4.BUILD-SNAPSHOT

spring-cloud-starter-gateway:2.0.4.BUILD-SNAPSHOT

spring-cloud-starter-openfeign:2.0.0.RELEASE

spring-boot:2.0.0.RELEASE

spring-boot-starter-data-jpa:2.0.0.RELEASE

spring-cloud-alibaba-seata:0.9.1.BUILD-SNAPSHOT

seata-all:0.6.1

mysql-connector-java:8.0.11

druid-spring-boot-starter:1.1.18

mysql:5.7

seata-server-0.6.1

實作:

zero-gateway-server

  • 配置application.yml
開源分布式事務中間件Seata使用指南

zero-provider-a:

開源分布式事務中間件Seata使用指南
  • File.conf

主要配置應用名稱和seata server位址

vgroup_mapping.${spring.application.name}-fescar-service-group="default"

default.grouplist = "127.0.0.1:8091"

開源分布式事務中間件Seata使用指南
  • Registry.conf
開源分布式事務中間件Seata使用指南
  • 編寫Entity
開源分布式事務中間件Seata使用指南
  • 編寫Repository
開源分布式事務中間件Seata使用指南
  • 編寫Service
開源分布式事務中間件Seata使用指南
  • 編寫代碼Controller
開源分布式事務中間件Seata使用指南
  • DataSource
開源分布式事務中間件Seata使用指南

zero-provider-b

配置同zero-provider-a工程,編寫相應的業務邏輯。

在處理添加業務時,抛出異常。

開源分布式事務中間件Seata使用指南

zero-consumer

  • feignClient
開源分布式事務中間件Seata使用指南
  • feignclient
開源分布式事務中間件Seata使用指南
  • Service
開源分布式事務中間件Seata使用指南
  • Controller
開源分布式事務中間件Seata使用指南

測試

啟動Seata Server

啟動Mysql,并初始化(每個庫都要建立undo_log表)

DROP SCHEMA IF EXISTS zeroa;

CREATE SCHEMA zeroa;

USE zeroa;



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;



DROP SCHEMA IF EXISTS zerob;

CREATE SCHEMA zerob;

USE zerob;



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;           

啟動

zero-discovery-server

zero-provider-a

添加資料

開源分布式事務中間件Seata使用指南

正常執行事務

開源分布式事務中間件Seata使用指南

可在兩張表中檢視資料(a庫中删除id=2的資料,b庫中添加了一條資料)。

執行事務復原

開源分布式事務中間件Seata使用指南

檢視資料庫資料(沒有變化)。

繼續閱讀