微服務應用整合SEATA實現分布式事務


概要

seata 是alibaba 出的一款分布式事務管理器,他有侵入性小,實現簡單等特點。我們能夠使用seata 實現分布式事務管理,

是微服務必備的組件。他可以實現在微服務之間的事務管理,也可以實現多個數據源的事務管理。

seata 在阿里內部,和眾多的公司都有應用,因此我們可以放心的使用它。

實現的基本原理

SEATA 實現了幾種事務模式,我們使用AT模式,他使用起來簡單,代碼侵入性小。

下圖就是AT的事務過程。

 

 

TM是事務管理者

RM 資源管理者,可以認為是數據庫。

TC 是事務協調者,就是SEATA 服務

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

 實現方式

配置SEATA

引入相關JAR包

<dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
                <version>2.1.1.RELEASE</version>
                <scope>compile</scope>
                <exclusions>
                    <exclusion>
                        <groupId>io.seata</groupId>
                        <artifactId>seata-all</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>

            <dependency>
                <groupId>io.seata</groupId>
                <artifactId>seata-all</artifactId>
                <version>1.2.0</version>
            </dependency>

在resources 下增加文件 registry.conf,我的實現為使用nacos作為配置和注冊中心

文件內容如下:

registry {
  type = "nacos"
  nacos {
    application = "seata-server"
    serverAddr = "192.168.31.10:8848"
    #namespace = "public"
    group = "DEFAULT_GROUP"
    #cluster = "default"
    #username = "nacos"
    #password = "nacos"
  }
}

config {
  type = "nacos"
  nacos {
    serverAddr = "192.168.31.10:8848"
    namespace = ""
    group = "SEATA_GROUP"
    cluster = "default"
    username = "nacos"
    password = "nacos"
  }
}

第一段是注冊中心的配置,第二段為配置中心的配置,配置實際上是放到nacos 下的。

配置文件路徑:

https://gitee.com/seata-io/seata/blob/develop/script/config-center/config.txt

可以把這個下下來,然后使用命令將這個配置,提交到 nacos,命令的路徑為:

https://gitee.com/seata-io/seata/tree/develop/script/config-center/nacos

 

 我們可以如下執行命令:

nacos-config.sh -h nacos的IP -p nacos端口 -u nacos用戶名 -w nacos密碼

這個配置需要修改的地方:

 

service.vgroupMapping.bpm_tx_group=default
service.vgroupMapping.form_tx_group=default
service.vgroupMapping.portal_tx_group=default
service.vgroupMapping.user_tx_group=default
service.vgroupMapping.system_tx_group=default

這個配置 為 

service.vgroupMapping + 應用的配置 =default 

 

 這個default 對應上面的配置

 

 事務數據存儲到數據庫

 

 

 

 修改 數據庫的配置,我們將配置導入到nacos 。

 

 同時,需要將剛剛的配置文件 registry.conf 拷貝到 seata 目錄下

 

 配置好后需要先啟動 nacos,在啟動 seata

 nohup ./seata-server.sh -p 8888 -h 192.168.31.10 &

 

seata 數據庫腳本:

https://gitee.com/seata-io/seata/blob/develop/script/server/db/mysql.sql

這樣 事務配置就處理好了。

 

我們需要在微服務的每個數據庫中增加 UNDO_LOG表。

CREATE TABLE IF NOT EXISTS `undo_log`
(
    `id`            BIGINT(20)   NOT NULL AUTO_INCREMENT COMMENT 'increment id',
    `branch_id`     BIGINT(20)   NOT NULL COMMENT 'branch transaction id',
    `xid`           VARCHAR(100) NOT NULL COMMENT 'global transaction id',
    `context`       VARCHAR(128) NOT NULL COMMENT 'undo_log context,such as serialization',
    `rollback_info` LONGBLOB     NOT NULL COMMENT 'rollback info',
    `log_status`    INT(11)      NOT NULL COMMENT '0:normal status,1:defense status',
    `log_created`   DATETIME     NOT NULL COMMENT 'create datetime',
    `log_modified`  DATETIME     NOT NULL COMMENT 'modify datetime',
    PRIMARY KEY (`id`),
    UNIQUE KEY `ux_undo_log` (`xid`, `branch_id`)
) ENGINE = InnoDB
  AUTO_INCREMENT = 1
  DEFAULT CHARSET = utf8 COMMENT ='AT transaction mode undo table';

這個需要和微服務數據庫在一起。

 

代碼實現

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



    @Bean("dataSourceProxy")
    public DataSourceProxy dataSourceProxy(@Qualifier("dataSource")DataSource dataSource) {
        DataSourceProxy proxy=new DataSourceProxy(dataSource);
        return proxy;
    }

 

 實際上我們在代碼中使用的是 DataSourceProxy 代理過的數據源。

測試如下:

 

 在測試時,我們可以發現,通過RootContext  取得Xid。

 


免責聲明!

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



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