Seata 分佈式事務 隨記

官網

AT模式:https://github.com/seata/seata/wiki/AT-Mode

流程解釋:http://seata.io/zh-cn/docs/overview/what-is-seata.html

AT流程圖解

https://www.cnblogs.com/smileIce/p/11200829.html

注意

1、表必須有主鍵。

2、截止到0.9版不支持聯合主鍵。可以用自增id做主鍵+聯合主鍵改爲唯一鍵。

3、UNDO_LOG表每個數據庫都創建,記錄全局事務Xid+表名+執行前/後鏡像 等信息用於回滾。

     在全局事務的每個子事務執行時,一起本地提交UNDO_LOG表(和本地業務在同一個事務中)。

4 、AT模式下,Seata爲全局事務涉及到的數據行在SeataServer中建立全局鎖(表名+主鍵),寫操作提交時需要先拿到此行數據的全局鎖,在全局事務提交時纔會釋放全局鎖。通過全局鎖(表+主鍵)保證同一行數據要在一個全局事務完成後,其他全局事務才能寫操作。

5、全局事務隔離性默認是讀未提交。因爲一個全局事務的每個子事務在執行後都是立即本地提交的,但是此時全局事務並未提交,而且還可能會回滾。但是此時其他查詢會讀到已經本地提交的數據。

官方的全局讀已提交隔離性通過select for update申請全局鎖實現

官方對隔離性的說明:https://github.com/seata/seata/wiki/AT-Mode

 

回滾實例,原代碼邏輯解析,bug坑分析

https://blog.csdn.net/flyfhj/article/details/99456100

檢驗開始
AbstractUndoExecutor.java的dataValidationAndGoOn方法

protected boolean dataValidationAndGoOn(Connection conn) throws SQLException {
    //數據修改前鏡像
    TableRecords beforeRecords = sqlUndoLog.getBeforeImage();
    //數據修改後鏡像
    TableRecords afterRecords = sqlUndoLog.getAfterImage();
    //如果修改前鏡像=修改後鏡像,說明數據沒有變更,無須回滾
    if (DataCompareUtils.isRecordsEquals(beforeRecords, afterRecords)) {
        return false;
    }
    //查找當前鏡像
    TableRecords currentRecords = queryCurrentRecords(conn);
    //如果當前鏡像**不等於**修改後鏡像,繼續對比
    if (!DataCompareUtils.isRecordsEquals(afterRecords, currentRecords)) {
            //如果當前鏡像**等於**修改前鏡像,說明數據沒有變更,無須回滾,否則爲髒數據直接拋出異常
            if (DataCompareUtils.isRecordsEquals(beforeRecords, currentRecords)) {

總結3點:
1、修改前鏡像等於修改後鏡像,說明數據沒有變更,無須回滾
2、當前鏡像等於修改後鏡像,則說明當前數據需要進行回滾
3、當前鏡像不等於修改後鏡像且當前鏡像等於修改前鏡像,說明數據無變更,無須回滾

舉例:

修改前鏡像 修改後鏡像 當前鏡像 是否回滾
5000 4700 5000 不回滾
5000 4700 4700 回滾
5000 5000 *** 不回滾
5000 4700 4400 髒數據&&不回滾

 

集成NACOS

https://blog.csdn.net/qq_27376871/article/details/91570779

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章