成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

詳細講解一下分布式事務-兩階段提交的實現(xiàn)原理

云計算 分布式
Seata(Simple Extensible Autonomous Transaction Architecture)是一款開源的分布式事務解決方案,提供了AT、TCC、SAGA和XA四種事務模式。其中,AT(Auto Transaction)模式是基于兩階段提交協(xié)議改進而來,通過數(shù)據(jù)源代理和全局鎖機制實現(xiàn)了對業(yè)務代碼幾乎零侵入的分布式事務支持。

一、為什么需要分布式事務

隨著微服務架構和分布式系統(tǒng)的普及,一個業(yè)務操作往往需要調用多個服務,修改多個數(shù)據(jù)源的數(shù)據(jù)。例如:

  • 電商系統(tǒng)中的下單操作:需要扣減庫存、創(chuàng)建訂單、支付等多個操作
  • 銀行轉賬操作:需要從一個賬戶扣款,另一個賬戶加款

這些操作需要作為一個整體要么全部成功,要么全部失敗,這就需要分布式事務來保證。

二、兩階段提交(2PC) 原理

兩階段提交(Two-Phase Commit,簡稱2PC)是分布式系統(tǒng)中實現(xiàn)分布式事務的經(jīng)典算法。它將事務的提交過程分為兩個階段:

  1. 準備階段(Prepare Phase):協(xié)調者詢問所有參與者是否可以提交
  2. 提交/回滾階段(Commit/Rollback Phase):根據(jù)準備階段的結果決定提交或回滾

角色劃分:

  • 協(xié)調者(Coordinator):事務的發(fā)起者,負責協(xié)調所有參與者
  • 參與者(Participant/Cohort):事務的實際執(zhí)行者,負責本地事務的執(zhí)行

兩階段提交流程:

(1)準備階段

  • 協(xié)調者向所有參與者發(fā)送prepare請求
  • 參與者執(zhí)行本地事務但不提交,記錄undo/redo日志
  • 參與者向協(xié)調者反饋響應:

成功:返回"同意"

失敗:返回"中止"

(2)提交/回滾階段

情況1:所有參與者都返回"同意"

  • 協(xié)調者向所有參與者發(fā)送commit請求
  • 參與者完成本地事務提交
  • 參與者向協(xié)調者發(fā)送ack響應
  • 協(xié)調者收到所有ack后完成事務

情況2:任一參與者返回"中止"或超時

  • 協(xié)調者向所有參與者發(fā)送rollback請求
  • 參與者利用undo日志回滾本地事務
  • 參與者向協(xié)調者發(fā)送ack響應
  • 協(xié)調者收到所有ack后中斷事務

三、基本實現(xiàn)示例

首先定義協(xié)調者和參與者的接口:

public interface Coordinator {
    void startTransaction(List<Participant> participants);
    boolean prepare();
    void commit();
    void rollback();
}


public interface Participant {
    boolean prepare();
    void commit();
    void rollback();
}

參與都實現(xiàn)代碼:

public class DatabaseParticipant implements Participant {
    private Connection connection;
    private String transactionId;


    public DatabaseParticipant(Connection connection, String transactionId) {
        this.connection = connection;
        this.transactionId = transactionId;
    }


    @Override
    public boolean prepare() {
        try {
            // 設置不自動提交
            connection.setAutoCommit(false);


            // 執(zhí)行SQL但不提交
            // 這里應該有實際的業(yè)務SQL,如:
            // PreparedStatement ps = connection.prepareStatement("UPDATE account SET balance = balance - 100 WHERE user_id = 1");
            // ps.executeUpdate();


            // 記錄redo/undo日志
            logRedoUndo();


            return true;
        } catch (SQLException e) {
            return false;
        }
    }


    @Override
    public void commit() {
        try {
            connection.commit();
            cleanRedoUndo();
        } catch (SQLException e) {
            // 處理異常
        }
    }


    @Override
    public void rollback() {
        try {
            connection.rollback();
            cleanRedoUndo();
        } catch (SQLException e) {
            // 處理異常
        }
    }


    private void logRedoUndo() {
        // 實現(xiàn)記錄redo/undo日志的邏輯
    }


    private void cleanRedoUndo() {
        // 清理日志
    }
}

協(xié)調者實現(xiàn)代碼:

public class TwoPhaseCommitCoordinator implements Coordinator {
    private List<Participant> participants;
    private String transactionId;


    public TwoPhaseCommitCoordinator(String transactionId) {
        this.transactionId = transactionId;
    }


    @Override
    public void startTransaction(List<Participant> participants) {
        this.participants = participants;
    }


    @Override
    public boolean prepare() {
        for (Participant participant : participants) {
            if (!participant.prepare()) {
                return false;
            }
        }
        return true;
    }


    @Override
    public void commit() {
        if (prepare()) {
            for (Participant participant : participants) {
                participant.commit();
            }
        } else {
            rollback();
        }
    }


    @Override
    public void rollback() {
        for (Participant participant : participants) {
            try {
                participant.rollback();
            } catch (Exception e) {
                // 記錄日志,繼續(xù)回滾其他參與者
            }
        }
    }
}

使用示例:

public class TwoPhaseCommitExample {
    public static void main(String[] args) {
        // 模擬兩個數(shù)據(jù)庫參與者
        Connection conn1 = getConnection(); // 獲取第一個數(shù)據(jù)庫連接
        Connection conn2 = getConnection(); // 獲取第二個數(shù)據(jù)庫連接


        Participant participant1 = new DatabaseParticipant(conn1, "tx123");
        Participant participant2 = new DatabaseParticipant(conn2, "tx123");


        Coordinator coordinator = new TwoPhaseCommitCoordinator("tx123");
        coordinator.startTransaction(Arrays.asList(participant1, participant2));


        try {
            coordinator.commit();
            System.out.println("事務提交成功");
        } catch (Exception e) {
            coordinator.rollback();
            System.out.println("事務回滾");
        }
    }


    private static Connection getConnection() {
        // 實際應用中應該從數(shù)據(jù)源獲取連接
        return null;
    }
}

四、Seata AT模式

Seata(Simple Extensible Autonomous Transaction Architecture)是一款開源的分布式事務解決方案,提供了AT、TCC、SAGA和XA四種事務模式。其中,AT(Auto Transaction)模式是基于兩階段提交協(xié)議改進而來,通過數(shù)據(jù)源代理和全局鎖機制實現(xiàn)了對業(yè)務代碼幾乎零侵入的分布式事務支持。

包含組件:

Transaction Coordinator (TC,事務協(xié)調器)

  • 獨立部署的服務,維護全局事務和分支事務的狀態(tài)
  • 負責協(xié)調全局事務的提交或回滾
  • 管理全局鎖的獲取與釋放

Transaction Manager (TM,事務管理器)

  • 嵌入在應用中,負責定義全局事務邊界
  • 通過@GlobalTransactional注解標記分布式事務方法
  • 向TC發(fā)起全局事務的開始、提交或回滾指令

Resource Manager (RM,資源管理器)

  • 管理分支事務上的資源
  • 向TC注冊分支事務并報告狀態(tài)
  • 驅動分支事務的提交或回滾
  • 負責生成和操作undo log

AT模式的整體流程:

(1)業(yè)務執(zhí)行與本地提交

  • 解析SQL:攔截業(yè)務SQL,解析SQL類型(INSERT/UPDATE/DELETE)、表、條件等信息
  • 查詢前鏡像:根據(jù)SQL條件查詢修改前的數(shù)據(jù)快照(before image)
  • 執(zhí)行業(yè)務SQL:執(zhí)行用戶的實際業(yè)務SQL
  • 查詢后鏡像:根據(jù)主鍵查詢修改后的數(shù)據(jù)快照(after image)
  • 插入回滾日志:將前后鏡像和業(yè)務SQL信息組成undo log記錄,插入到undo_log表
  • 注冊分支事務:向TC注冊分支事務并獲取全局鎖
  • 提交本地事務:業(yè)務SQL和undo log在同一個本地事務中提交
  • 上報執(zhí)行結果:將本地事務執(zhí)行結果上報給TC

(2)全局提交或回滾

全局提交:

  • TC異步通知各分支事務提交
  • RM異步刪除對應的undo log記錄
  • 釋放全局鎖

全局回滾:

  • TC通知各分支事務回滾
  • RM根據(jù)undo log中的before image生成補償SQL并執(zhí)行
  • 校驗數(shù)據(jù)一致性(對比after image與當前數(shù)據(jù))
  • 刪除undo log記錄
  • 釋放全局鎖

Seata的詳細信息,請查看官網(wǎng):https://seata.apache.org/zh-cn/docs/dev/mode/at-mode

五、兩階段提交的問題

(1)協(xié)調者單點故障

如果在第二階段協(xié)調者宕機,部分參與者收到commit而部分沒收到,系統(tǒng)將處于不一致狀態(tài)。

解決方法:記錄事務日志,協(xié)調者恢復后能繼續(xù)處理。

(2)網(wǎng)絡分區(qū)

網(wǎng)絡分區(qū)可能導致部分參與者無法收到協(xié)調者的指令。

為了解決2PC的網(wǎng)絡阻塞問題,引入了3PC:

  • CanCommit階段:詢問參與者是否可以提交
  • PreCommit階段:預提交,執(zhí)行事務但不提交
  • DoCommit階段:實際提交

3PC通過引入超時機制減少了阻塞,但增加了復雜度。

責任編輯:武曉燕 來源: 全棧程序員老馬
相關推薦

2025-06-10 08:02:15

2023-07-26 09:24:03

分布式事務分布式系統(tǒng)

2024-01-26 08:18:03

2018-10-29 08:44:29

分布式兩階段提交事務

2024-05-21 14:12:07

2022-12-21 19:04:35

InnoDBMySQL

2010-04-22 15:11:14

2023-12-05 09:33:08

分布式事務

2024-03-26 16:24:46

分布式事務2PC3PC

2022-06-21 08:27:22

Seata分布式事務

2022-06-27 08:21:05

Seata分布式事務微服務

2025-06-19 08:03:03

2022-03-28 10:44:51

MySQL日志存儲

2023-11-29 07:47:58

DDIA兩階段提交

2023-12-26 08:59:52

分布式場景事務機制

2019-08-19 10:24:33

分布式事務數(shù)據(jù)庫

2021-03-17 00:05:50

分布式事務提交

2023-10-24 08:25:20

TCC模式事務

2024-11-28 15:11:28

2022-07-10 20:24:48

Seata分布式事務
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 成人精品国产一区二区4080 | 欧美日韩成人影院 | 国产专区免费 | 日韩日b视频 | 一区二区三区四区在线播放 | 中文字幕的av | 欧美xxxx性xxxxx高清 | 欧美一区二区三区,视频 | jvid精品资源在线观看 | 99re视频在线 | 免费久久视频 | 欧美综合国产精品久久丁香 | 久婷婷 | 91精品国产高清久久久久久久久 | 久久高清 | 青青草视频网 | 久久国产精品72免费观看 | 色婷婷一区二区三区四区 | 成人一区二区视频 | 免费在线精品视频 | 亚洲欧美一区二区三区国产精品 | 亚洲精品久久 | 亚洲一区二区高清 | 国产三级 | 日韩视频在线免费观看 | 一二三区在线 | 九九久久精品 | a级毛片免费高清视频 | 在线视频a | 成人在线a | 日韩亚洲视频 | 视频1区2区 | 欧美一级电影免费观看 | 三级黄色网址 | 精品久久久久久久人人人人传媒 | 欧美日韩大片 | 成人在线播放 | 欧美午夜一区 | 国产不卡一区在线观看 | www精品| 国产在线精品一区二区三区 |