欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Seata之分布式事務(wù)問題及解決方案

 更新時間:2025年03月13日 14:15:40   作者:L_?。?!  
這篇文章主要介紹了Seata之分布式事務(wù)問題及解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教

Seata–分布式事務(wù)解決方案

簡介

Seata 是阿里開源的分布式事務(wù)解決方案,提供 ATXA、TCC、Saga 四種事務(wù)模式,支持微服務(wù)架構(gòu)下的數(shù)據(jù)一致性。

官網(wǎng):https://seata.apache.org/zh-cn/

同類產(chǎn)品對比

方案核心特點(diǎn)適用場景
Seata多模式支持,代碼侵入性低,社區(qū)活躍復(fù)雜業(yè)務(wù)場景,需靈活選擇模式
阿里云 GTS商業(yè)版方案,功能全面,性能強(qiáng)企業(yè)級付費(fèi)場景
RocketMQ 事務(wù)消息基于消息隊(duì)列實(shí)現(xiàn)最終一致性異步高吞吐場景
LCN基于代理模式,實(shí)現(xiàn)簡單輕量級快速接入

環(huán)境搭建

1.微服務(wù)

創(chuàng)建 Spring Cloud 項(xiàng)目,推薦使用以下組件:

<!-- Spring Cloud Alibaba 依賴 -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>

2.SQL

每個微服務(wù)數(shù)據(jù)庫需創(chuàng)建 undo_log 表(AT模式必需):

-- 每個業(yè)務(wù)數(shù)據(jù)庫均需執(zhí)行
CREATE TABLE IF NOT EXISTS `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,
    PRIMARY KEY (`id`),
    UNIQUE KEY `ux_undo_log` (`xid`, `branch_id`)
) ENGINE = InnoDB
  AUTO_INCREMENT = 1
  DEFAULT CHARSET = utf8;

3.seata-server

  • 1.下載 :https://seata.apache.org/zh-cn/download/seata-server
  • 2.解壓并啟動:seata-server.bat
  • 3.控制臺:http://127.0.0.1:7091/#/transaction/list

4.微服務(wù)配置

依賴

除基礎(chǔ)依賴外需添加:

<dependency>
  <groupId>com.alibaba.cloud</groupId>
  <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>

配置

每個微服務(wù)創(chuàng)建 file.conf文件,完整內(nèi)容如下;

【微服務(wù)只需要復(fù)制 service 塊配置即可】

#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

transport {
  # tcp, unix-domain-socket
  type = "TCP"
  #NIO, NATIVE
  server = "NIO"
  #enable heartbeat
  heartbeat = true
  # the tm client batch send request enable
  enableTmClientBatchSendRequest = false
  # the rm client batch send request enable
  enableRmClientBatchSendRequest = true
   # the rm client rpc request timeout
  rpcRmRequestTimeout = 2000
  # the tm client rpc request timeout
  rpcTmRequestTimeout = 30000
  # the rm client rpc request timeout
  rpcRmRequestTimeout = 15000
  #thread factory for netty
  threadFactory {
    bossThreadPrefix = "NettyBoss"
    workerThreadPrefix = "NettyServerNIOWorker"
    serverExecutorThread-prefix = "NettyServerBizHandler"
    shareBossWorker = false
    clientSelectorThreadPrefix = "NettyClientSelector"
    clientSelectorThreadSize = 1
    clientWorkerThreadPrefix = "NettyClientWorkerThread"
    # netty boss thread size
    bossThreadSize = 1
    #auto default pin or 8
    workerThreadSize = "default"
  }
  shutdown {
    # when destroy server, wait seconds
    wait = 3
  }
  serialization = "seata"
  compressor = "none"
}
service {
  #transaction service group mapping
  vgroupMapping.default_tx_group = "default"
  #only support when registry.type=file, please don't set multiple addresses
  default.grouplist = "127.0.0.1:8091"
  #degrade, current not support
  enableDegrade = false
  #disable seata
  disableGlobalTransaction = false
}

client {
  rm {
    asyncCommitBufferLimit = 10000
    lock {
      retryInterval = 10
      retryTimes = 30
      retryPolicyBranchRollbackOnConflict = true
    }
    reportRetryCount = 5
    tableMetaCheckEnable = false
    tableMetaCheckerInterval = 60000
    reportSuccessEnable = false
    sagaBranchRegisterEnable = false
    sagaJsonParser = "fastjson"
    sagaRetryPersistModeUpdate = false
    sagaCompensatePersistModeUpdate = false
    tccActionInterceptorOrder = -2147482648 #Ordered.HIGHEST_PRECEDENCE + 1000
    sqlParserType = "druid"
    branchExecutionTimeoutXA = 60000
    connectionTwoPhaseHoldTimeoutXA = 10000
  }
  tm {
    commitRetryCount = 5
    rollbackRetryCount = 5
    defaultGlobalTransactionTimeout = 60000
    degradeCheck = false
    degradeCheckPeriod = 2000
    degradeCheckAllowTimes = 10
    interceptorOrder = -2147482648 #Ordered.HIGHEST_PRECEDENCE + 1000
  }
  undo {
    dataValidation = true
    onlyCareUpdateColumns = true
    logSerialization = "jackson"
    logTable = "undo_log"
    compress {
      enable = true
      # allow zip, gzip, deflater, lz4, bzip2, zstd default is zip
      type = zip
      # if rollback info size > threshold, then will be compress
      # allow k m g t
      threshold = 64k
    }
  }
  loadBalance {
      type = "XID"
      virtualNodes = 10
  }
}
log {
  exceptionRate = 100
}
tcc {
  fence {
    # tcc fence log table name
    logTableName = tcc_fence_log
    # tcc fence log clean period
    cleanPeriod = 1h
  }
}

事務(wù)模式

1.AT模式(推薦:自動補(bǔ)償)

二階提交協(xié)議原理

原理:基于反向SQL補(bǔ)償,自動生成回滾日志

使用

@Service
public class OrderService {
    @GlobalTransactional(name = "createOrder", timeoutMills = 60000)
    public void createOrder(OrderDTO order) {
        // 1. 扣減庫存(調(diào)用庫存服務(wù))
        storageFeignClient.deduct(order.getProductId());
        // 2. 創(chuàng)建訂單(本地事務(wù))
        orderMapper.insert(order);
        // 3. 模擬異常觸發(fā)回滾
        int i = 1 / 0; 
    }
}

關(guān)鍵機(jī)制

  • 一階段:提交本地事務(wù),生成回滾日志(undo_log)
  • 二階段:成功則異步刪除日志,失敗則通過日志反向補(bǔ)償

特點(diǎn)

  • 對代碼無侵入
  • 需創(chuàng)建undo_log表
  • 適用于大多數(shù)CRUD場景

2.XA模式(強(qiáng)一致)

原理:基于數(shù)據(jù)庫XA協(xié)議的兩階段提交

配置

seata:
  data-source-proxy-mode: XA  # 默認(rèn)AT

特點(diǎn):

  • 基于數(shù)據(jù)庫XA協(xié)議
  • 兩階段提交(2PC)
  • 事務(wù)持有鎖時間較長,適合短事務(wù)

適用場景:強(qiáng)一致性需求,支持XA協(xié)議的數(shù)據(jù)庫(如MySQL 5.7+)

3.TCC模式(手動補(bǔ)償)

原理:Try-Confirm-Cancel 三階段控制

實(shí)現(xiàn)

// 1. 定義TCC接口
public interface StorageTccService {
    @TwoPhaseBusinessAction(name = "deduct", 
                          commitMethod = "confirm", 
                          rollbackMethod = "cancel")
    boolean deduct(@BusinessActionContextParameter(paramName = "productId") String productId,
                   @BusinessActionContextParameter(paramName = "count") Integer count);
    
    boolean confirm(BusinessActionContext context);
    boolean cancel(BusinessActionContext context);
}

// 2. 實(shí)現(xiàn)Try邏輯
@Service
public class StorageTccServiceImpl implements StorageTccService {
    @Override
    public boolean deduct(String productId, Integer count) {
        // Try階段:資源預(yù)留(例如凍結(jié)庫存)
        return storageMapper.freezeStock(productId, count) > 0;
    }
    
    @Override
    public boolean confirm(BusinessActionContext context) {
        // Confirm階段:真實(shí)扣減(例如刪除凍結(jié)記錄)
        String productId = context.getActionContext("productId");
        Integer count = context.getActionContext("count");
        return storageMapper.reduceStock(productId, count) > 0;
    }
    
    @Override
    public boolean cancel(BusinessActionContext context) {
        // Cancel階段:釋放資源(例如恢復(fù)凍結(jié)庫存)
        String productId = context.getActionContext("productId");
        Integer count = context.getActionContext("count");
        return storageMapper.unfreezeStock(productId, count) > 0;
    }
}

使用限制:

  • 需自行實(shí)現(xiàn)Try/Confirm/Cancel方法
  • Confirm和Cancel需保證冪等性

特點(diǎn):高性能,但需手動編寫補(bǔ)償邏輯

4.Saga模式(長事務(wù))

實(shí)現(xiàn)方式:

通過狀態(tài)機(jī)配置補(bǔ)償策略:

@SagaStart
public void createOrderSaga(Order order) {
    // 1. 創(chuàng)建訂單
    orderService.create(order);
    // 2. 調(diào)用支付服務(wù)(若失敗則觸發(fā)逆向操作)
    paymentService.pay(order.getId());
}
// 定義補(bǔ)償方法
@Compensate
public void compensateOrder(Order order) {
    orderService.delete(order.getId());
}

原理:長事務(wù)拆分+逆向補(bǔ)償

適用場景:跨系統(tǒng)長時間操作(如訂單+物流+支付)

總結(jié)

模式選型對照表:

模式一致性性能侵入性適用場景
AT弱一致常規(guī)業(yè)務(wù)(庫存扣減、訂單創(chuàng)建)
TCC強(qiáng)一致資金交易、需精準(zhǔn)控制
XA強(qiáng)一致銀行轉(zhuǎn)賬、短事務(wù)
Saga最終一致跨系統(tǒng)長流程(訂單+物流+支付)

核心要點(diǎn):

分類要點(diǎn)說明
選型AT模式適用于大多數(shù)場景,TCC適合高性能要求,XA適合強(qiáng)一致性
配置確保seata-server與微服務(wù)的registry配置一致
事務(wù)ID通過RootContext.getXID()可獲取當(dāng)前事務(wù)ID
排錯檢查undo_log表記錄,查看seata-server控制臺日志

最佳實(shí)踐:

  1. 生產(chǎn)環(huán)境建議使用Nacos作為配置中心
  2. AT模式需要開啟數(shù)據(jù)庫的本地事務(wù)支持(如MySQL的InnoDB引擎)
  3. 全局事務(wù)超時時間建議設(shè)置:seata.tx.timeout=60000(單位毫秒)

以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Maven dependency中的scope案例講解

    Maven dependency中的scope案例講解

    Maven的一個哲學(xué)是慣例優(yōu)于配置(Convention Over Configuration), Maven默認(rèn)的依賴配置項(xiàng)中,scope的默認(rèn)值是compile,本文給大家介紹Maven dependency中的scope案例講解,感興趣的朋友跟隨小編一起看看吧
    2024-02-02
  • postman?如何實(shí)現(xiàn)傳遞?ArrayList?給后臺

    postman?如何實(shí)現(xiàn)傳遞?ArrayList?給后臺

    這篇文章主要介紹了postman?如何實(shí)現(xiàn)傳遞?ArrayList給后臺,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • 深入理解JVM之類加載機(jī)制詳解

    深入理解JVM之類加載機(jī)制詳解

    這篇文章主要介紹了深入理解JVM之類加載機(jī)制,結(jié)合實(shí)例形式詳細(xì)分析了類加載機(jī)制原理、過程及相關(guān)操作注意事項(xiàng),需要的朋友可以參考下
    2019-09-09
  • Java中間的接口用法詳解

    Java中間的接口用法詳解

    Java 程序員都知道要面向接口編程,那 Java? 中的接口除了定義接口方法之外還能怎么用你知道嗎,今天小編就來帶大家看一下 Java 中間的接口還可以有哪些用法,需要的朋友可以參考下
    2023-07-07
  • 解決@SpringBootTest 單元測試遇到的坑

    解決@SpringBootTest 單元測試遇到的坑

    這篇文章主要介紹了解決@SpringBootTest 單元測試遇到的坑,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • Java 8系列之Stream中萬能的reduce用法說明

    Java 8系列之Stream中萬能的reduce用法說明

    這篇文章主要介紹了Java 8系列之Stream中萬能的reduce用法說明,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-08-08
  • 關(guān)于Java并發(fā)編程中線程間協(xié)作的兩種方式

    關(guān)于Java并發(fā)編程中線程間協(xié)作的兩種方式

    這篇文章主要介紹了關(guān)于Java并發(fā)編程中線程間協(xié)作的兩種方式,當(dāng)隊(duì)列滿時,生產(chǎn)者需要等待隊(duì)列有空間才能繼續(xù)往里面放入商品,而在等待的期間內(nèi),生產(chǎn)者必須釋放對臨界資源的占用權(quán),這是消費(fèi)者模式,需要的朋友可以參考下
    2023-07-07
  • Spring Cloud Gateway 內(nèi)存溢出的解決方案

    Spring Cloud Gateway 內(nèi)存溢出的解決方案

    這篇文章主要介紹了Spring Cloud Gateway 內(nèi)存溢出的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • Spring-Cloud Eureka注冊中心實(shí)現(xiàn)高可用搭建

    Spring-Cloud Eureka注冊中心實(shí)現(xiàn)高可用搭建

    這篇文章主要介紹了Spring-Cloud Eureka注冊中心實(shí)現(xiàn)高可用搭建,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-04-04
  • Java自定義實(shí)現(xiàn)鏈隊(duì)列詳解

    Java自定義實(shí)現(xiàn)鏈隊(duì)列詳解

    這篇文章主要為大家詳細(xì)介紹了Java自定義實(shí)現(xiàn)鏈隊(duì)列的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-12-12

最新評論