首頁 > 軟體

springcloud整合seata的實現程式碼

2022-05-20 19:06:26

一、背景

上一篇文章中,我們使用Seata整合了SpringBoot,在這篇文章中我們使用Seata整合SpringCloud。同時有了上一篇文章的基礎,此處我們簡單實現。

二、專案結構

三、實現功能:

完成使用者下單操作,下單分為呼叫 賬戶服務 扣除餘額,呼叫訂單服務建立訂單。

四、專案使用到的技術

Spring Cloud 、eureka、openfeign、seata 、nacos、druid、mybatis-plus

五、整合步驟

1、引入spring-cloud-starter-alibaba-seata jar包

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
    <version>2021.1</version>
    <exclusions>
        <exclusion>
            <artifactId>seata-spring-boot-starter</artifactId>
            <groupId>io.seata</groupId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>io.seata</groupId>
    <artifactId>seata-spring-boot-starter</artifactId>
    <version>1.4.2</version>
</dependency>

參考檔案: https://seata.io/zh-cn/docs/ops/deploy-guide-beginner.html

2、涉及到的業務庫操作

1、業務庫需要存在 undo_log 表

CREATE TABLE IF NOT EXISTS `undo_log`
(
    `branch_id`     BIGINT       NOT NULL COMMENT 'branch transaction id',
    `xid`           VARCHAR(128) 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(6)  NOT NULL COMMENT 'create datetime',
    `log_modified`  DATETIME(6)  NOT NULL COMMENT 'modify datetime',
    UNIQUE KEY `ux_undo_log` (`xid`, `branch_id`)
) ENGINE = InnoDB COMMENT ='AT transaction mode undo table';

2、業務表主鍵

業務表中必須包含單列主鍵,如果存在多列主鍵,則目前只有mysql支援。

3、頁面中自動更新時間戳

業務表中最好不要自動更新時間戳,使用手動更新,更新資料,只更新用到的資料。
比如:
表中存在10個欄位,當前業務只需要更新3個欄位,此時我們更新3個欄位即可,不要更新10個欄位,如果update_time欄位是預設更新的,則使用手動更新。

3、開啟資料來源代理

1、自動設定資料來源代理

seata:
  enabled: true
  # 是否自動開啟資料來源代理
  enable-auto-data-source-proxy: true
  # 資料來源代理模式,使用AT模式
  data-source-proxy-mode: AT

2、手動設定AT模式資料來源代理

1、組態檔關閉自動資料來源代理

seata:
  # 是否自動開啟資料來源代理
  enable-auto-data-source-proxy: false

2、設定設定資料來源

AT模式下返回的資料來源一定需要是 DataSourceProxy

@Bean
    public DataSource dataSourceProxy() {
        // 某一個資料來源
        XxxDataSource xxxDataSource = new XxxDataSource();
        // 設定資料來源的各種設定屬性
        xxxDataSource.setXXX("");
        // 使用 DataSourceProxy 來包裝一下
        return new DataSourceProxy(xxxDataSource);
    }

4、傳遞 xid

在引入了 spring-cloud-starter-alibaba-seata 後,很多都已經實現了自動傳遞 xid 。同時在分散式事務結束後,需要清除xid的值。

預設實現了 feignrestweb3種方式的 xid的傳遞。

5、事務分組和seata server對應上

6、註冊中心和設定中心

應用程式中 seata 的設定中心和 註冊中心 需要和 seata server 的保持一致。

7、業務方法加上@GlobalTransactional 註解

在需要開啟分散式事務的方法上加入 @GlobalTransactional 註解,開啟分散式事務。

public class BusinessServiceImpl implements BusinessService {
    private final OrderService orderService;
    private final AccountClient accountClient;
    @Override
    // 開啟分散式事務
    @GlobalTransactional(rollbackFor = Exception.class)
    public void createAccountOrder(Integer accountId, Long amount, boolean hasException) {
        System.out.println("xid:" + RootContext.getXID());
        // 1、遠端扣減賬戶餘額
        remoteDebit(accountId, amount);
        // 2、下訂單
        orderService.createOrder(accountId, amount);
        if (hasException) {
            throw new RuntimeException("發生了異常,分散式事物需要會滾");
        }
    }
    private void remoteDebit(Integer accountId, Long amount) {
        String result = accountClient.debit(accountId, amount);
        log.info("遠端扣減庫存結果:[{}]", result);
    }
}

六、演示

分散式事務發生異常,事務回滾

七、完整程式碼

https://gitee.com/huan1993/spring-cloud-parent/tree/master/seata/seata-springcloud-mybatis-plus

八、參考檔案

1、新人檔案

2、seata常見問題

到此這篇關於springcloud整合seata的文章就介紹到這了,更多相關springcloud整合seata內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com