介紹java
Seata 是阿里巴巴開源的分佈式事務中間件,一種分佈式事務解決方案,具備高性能和易於使用的微服務架構。mysql
初衷git
對業務無侵入:即減小技術架構上的微服務化所帶來的分佈式事務問題對業務的侵入github
高性能:減小分佈式事務解決方案所帶來的性能消耗spring
分佈式事務定義sql
分佈式事務是一個全局事務,由一批分支事務組成,一般分支事務只是本地事務。數據庫
設計bash
Seata中有兩種分佈式事務實現方案,AT和TCC。架構
ATapp
AT模式是基於XA事務演進而來,核心是對業務無侵入,是一種改進後的兩階段提交,須要數據庫支持。
基本組件:
事務協調器(TC):事務協調器,維護全局事務的運行狀態,負責協調並驅動全局事務的提交或回滾。
Transaction Manager(TM): 控制全局事務的邊界,負責開啓一個全局事務,並最終發起全局提交或全局回滾的決議。
資源管理器(RM):控制分支事務,負責分支註冊、狀態彙報,並接收事務協調器的指令,驅動分支(本地)事務的提交和回滾。
處理流程:
TM要求TC開始新的全局事務。TC生成表示全局事務的XID。
XID經過微服務的調用鏈傳播。
RM將本地事務註冊爲XID到TC的相應全局事務的分支。
TM要求TC提交或回滾XID的相應全局事務。
TC在XID的相應全局事務下驅動全部分支事務以完成分支提交或回滾。
TCC
Seata要求每一個接口實現prepare、commit、rollback。
與 AT 模式同樣,在運行時,該切面會攔截全部對 TCC 接口的調用。每調用一次 Try 接口,切面會先向 TC 註冊一個分支事務,而後纔去執行原來的 RPC 調用。當請求鏈路調用完成後,TC 經過分支事務的資源 ID 回調到正確的參與者去執行對應 TCC 資源的 Confirm 或 Cancel 方法。
初步操做 Try:完成全部業務檢查,預留必須的業務資源。
確認操做 Confirm:真正執行的業務邏輯,不作任何業務檢查,只使用 Try 階段預留的業務資源。所以,只要 Try 操做成功,Confirm 必須能成功。另外,Confirm 操做需知足冪等性,保證一筆分佈式事務能且只能成功一次。
取消操做 Cancel:釋放 Try 階段預留的業務資源。一樣的,Cancel 操做也須要知足冪等性。
Seata Server安裝
1.下載最新版本的 Seata Sever
https://github.com/seata/seata/releases
2. 解壓並啓動 Seata server
unzip seata-server-xxx.zipcd distributionsh ./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
zero-provider-a:
配置application.yml
File.conf
主要配置應用名稱和seata server地址
vgroup_mapping.${spring.application.name}-fescar-service-group="default"
default.grouplist = "127.0.0.1:8091"
Registry.conf
編寫Entity
編寫Repository
編寫Service
編寫代碼Controller
DataSource
zero-provider-b
配置同zero-provider-a工程,編寫相應的業務邏輯。
在處理添加業務時,拋出異常。
zero-consumer
配置同zero-provider-a工程,編寫相應的業務邏輯。
feignClient
feignclient
Service
Controller
測試
啓動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-gateway-server
zero-provider-a
zero-provider-b
zero-consumer
添加數據
正常執行事務
可在兩張表中查看數據(a庫中刪除id=2的數據,b庫中添加了一條數據)。
執行事務回滾
查看數據庫數據(沒有變化)。