新版seata來了蕾域,我們一起來拆箱看看有哪些變化

一信粮、seata是什么

Seata 是一款開源的分布式事務(wù)解決方案,致力于提供高性能和簡單易用的分布式事務(wù)服務(wù)梦皮。Seata 將為用戶提供了 AT炭分、TCC、SAGA 和 XA 事務(wù)模式剑肯,為用戶打造一站式的分布式解決方案捧毛。

seata官方網(wǎng)站

在19年初的時候就關(guān)注過這個中間件(當(dāng)時叫Fescar),并且對它的源碼進行了一下分析--阿里分布式事務(wù)解決方案fescar簡析让网。然而當(dāng)時并不成熟呀忧,并不能直接用于商用,主要有以下幾個問題溃睹。

  • TC的實現(xiàn)不完善而账。不支持HA,xid的生成因篇,session的存儲泞辐,鎖的實現(xiàn)等都是以DEMO的方式提供,不能直接用于線上環(huán)境竞滓,需要二次開發(fā)
  • 回滾失敗的補償機制不完善
  • 性能問題咐吼。seata當(dāng)時宣稱只有在第一階段提交的時候進行加鎖,相對傳統(tǒng)的兩階段提交對性能有比較大的提升商佑。但現(xiàn)實情況是為了保證回滾操作的成功锯茄,還必須要有一個全局鎖,事實上相比XA的方式我個人認為在系統(tǒng)的吞吐量上個人認為不會有太大的變化茶没。而且由于這種方式實現(xiàn)的是類似補償性事務(wù)的方式肌幽,又會引入一個可見性的問題(第二階段提交前就已經(jīng)能看到第一階段提交的結(jié)果)
  • RPC框架。由于是阿里系的中間件抓半,因此第一版實現(xiàn)的是基于dubbo喂急,非dubbo的rpc框架需要根據(jù)自己的情況做二次開發(fā)。

二笛求、模式

  • AT
  • TCC
  • SAGA(新特性)
  • XA(新特性)

三煮岁、核心組件

  • TC

事務(wù)協(xié)調(diào)者

  • TM

事務(wù)發(fā)起者讥蔽。定義事務(wù)邊界

  • RM

事務(wù)參與者

四、demo演示

五画机、源碼分析

注:本文使用的版本為v1.2.0

1. undo_log的產(chǎn)生和刪除機制

  • undo_log的產(chǎn)生
UndoLogManager類圖

查看flushUndoLogs調(diào)用棧

flushUndoLogs:200, AbstractUndoLogManager (io.seata.rm.datasource.undo)
processGlobalTransactionCommit:221, ConnectionProxy (io.seata.rm.datasource)
doCommit:196, ConnectionProxy (io.seata.rm.datasource)
lambda$commit$0:184, ConnectionProxy (io.seata.rm.datasource)
call:-1, 362578118 (io.seata.rm.datasource.ConnectionProxy$$Lambda$197)
execute:289, ConnectionProxy$LockRetryPolicy (io.seata.rm.datasource)
commit:183, ConnectionProxy (io.seata.rm.datasource)
...
execute:108, ExecuteTemplate (io.seata.rm.datasource.exec)
execute:49, ExecuteTemplate (io.seata.rm.datasource.exec)
...
update:927, JdbcTemplate (org.springframework.jdbc.core)
deduct:51, StorageServiceImpl (io.seata.samples.dubbo.service.impl)

ConnectionProxy為Connection的代理類。

private void processGlobalTransactionCommit() throws SQLException {
        try {
            //**新特性新症,分支事務(wù)注冊到TC改為在提交前進行步氏,而不是在一開始就獲取一個branchId
            register();
        } catch (TransactionException e) {
            recognizeLockKeyConflictException(e, context.buildLockKeys());
        }
        try {
            //根據(jù)數(shù)據(jù)庫的類型獲取對應(yīng)的UndoLogManager進行刷寫undolog日志
            UndoLogManagerFactory.getUndoLogManager(this.getDbType()).flushUndoLogs(this);
            //原connection的commit操作
            targetConnection.commit();
        } catch (Throwable ex) {
            LOGGER.error("process connectionProxy commit error: {}", ex.getMessage(), ex);
            report(false);
            throw new SQLException(ex);
        }
        if (IS_REPORT_SUCCESS_ENABLE) {
            report(true);
        }
        context.reset();
    }

AbstractUndoLogManager.java

@Override
    public void flushUndoLogs(ConnectionProxy cp) throws SQLException {
        //通過連接代理獲取連接的上下文,這里先不分析xid的傳遞機制徒爹,留給后面的部分進行分析
        ConnectionContext connectionContext = cp.getContext();
        if (!connectionContext.hasUndoLog()) {
            return;
        }

        String xid = connectionContext.getXid();
        long branchId = connectionContext.getBranchId();

        BranchUndoLog branchUndoLog = new BranchUndoLog();
        branchUndoLog.setXid(xid);
        branchUndoLog.setBranchId(branchId);
        //具體的undolog的內(nèi)容
        branchUndoLog.setSqlUndoLogs(connectionContext.getUndoItems());

        UndoLogParser parser = UndoLogParserFactory.getInstance();
        byte[] undoLogContent = parser.encode(branchUndoLog);

        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("Flushing UNDO LOG: {}", new String(undoLogContent, Constants.DEFAULT_CHARSET));
        }
        //實際的寫入操作荚醒,不同的關(guān)系型數(shù)據(jù)庫有不同的實現(xiàn)
        insertUndoLogWithNormal(xid, branchId, buildContext(parser.getName()), undoLogContent,
            cp.getTargetConnection());
    }

為了直觀顯示,我這里給出了一條undo_log的數(shù)據(jù)

           id: 32
    branch_id: 2011290555
          xid: 172.17.0.1:8091:2011290554
      context: serializer=jackson
rollback_info: {"@class":"io.seata.rm.datasource.undo.BranchUndoLog","xid":"172.17.0.1:8091:2011290554","branchId":2011290555,"sqlUndoLogs":["java.util.ArrayList",[{"@class":"io.seata.rm.datasource.undo.SQLUndoLog","sqlType":"UPDATE","tableName":"storage_tbl","beforeImage":{"@class":"io.seata.rm.datasource.sql.struct.TableRecords","tableName":"storage_tbl","rows":["java.util.ArrayList",[{"@class":"io.seata.rm.datasource.sql.struct.Row","fields":["java.util.ArrayList",[{"@class":"io.seata.rm.datasource.sql.struct.Field","name":"id","keyType":"PRIMARY_KEY","type":4,"value":4},{"@class":"io.seata.rm.datasource.sql.struct.Field","name":"count","keyType":"NULL","type":4,"value":201}]]}]]},"afterImage":{"@class":"io.seata.rm.datasource.sql.struct.TableRecords","tableName":"storage_tbl","rows":["java.util.ArrayList",[{"@class":"io.seata.rm.datasource.sql.struct.Row","fields":["java.util.ArrayList",[{"@class":"io.seata.rm.datasource.sql.struct.Field","name":"id","keyType":"PRIMARY_KEY","type":4,"value":4},{"@class":"io.seata.rm.datasource.sql.struct.Field","name":"count","keyType":"NULL","type":4,"value":199}]]}]]}}]]}
   log_status: 0
  log_created: 2020-05-10 10:02:53
 log_modified: 2020-05-10 10:02:53
          ext: NULL

這個操作為把用戶的庫存記錄-2隆嗅。beforeImage的count為201界阁,afterImage的count為199。

  • RPC框架整合(xid傳遞)
  • 鎖的機制(全局鎖和局部鎖)
  • session狀態(tài)存儲
  • 全局ID生成
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末胖喳,一起剝皮案震驚了整個濱河市泡躯,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌丽焊,老刑警劉巖较剃,帶你破解...
    沈念sama閱讀 212,816評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異技健,居然都是意外死亡写穴,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,729評論 3 385
  • 文/潘曉璐 我一進店門雌贱,熙熙樓的掌柜王于貴愁眉苦臉地迎上來啊送,“玉大人,你說我怎么就攤上這事欣孤〔雒唬” “怎么了?”我有些...
    開封第一講書人閱讀 158,300評論 0 348
  • 文/不壞的土叔 我叫張陵导街,是天一觀的道長披泪。 經(jīng)常有香客問我,道長搬瑰,這世上最難降的妖魔是什么款票? 我笑而不...
    開封第一講書人閱讀 56,780評論 1 285
  • 正文 為了忘掉前任,我火速辦了婚禮泽论,結(jié)果婚禮上艾少,老公的妹妹穿的比我還像新娘。我一直安慰自己翼悴,他們只是感情好缚够,可當(dāng)我...
    茶點故事閱讀 65,890評論 6 385
  • 文/花漫 我一把揭開白布幔妨。 她就那樣靜靜地躺著,像睡著了一般谍椅。 火紅的嫁衣襯著肌膚如雪误堡。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,084評論 1 291
  • 那天雏吭,我揣著相機與錄音锁施,去河邊找鬼。 笑死杖们,一個胖子當(dāng)著我的面吹牛悉抵,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播摘完,決...
    沈念sama閱讀 39,151評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼姥饰,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了孝治?” 一聲冷哼從身側(cè)響起列粪,我...
    開封第一講書人閱讀 37,912評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎荆秦,沒想到半個月后篱竭,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,355評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡步绸,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,666評論 2 327
  • 正文 我和宋清朗相戀三年掺逼,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片瓤介。...
    茶點故事閱讀 38,809評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡吕喘,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出刑桑,到底是詐尸還是另有隱情氯质,我是刑警寧澤,帶...
    沈念sama閱讀 34,504評論 4 334
  • 正文 年R本政府宣布祠斧,位于F島的核電站闻察,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏琢锋。R本人自食惡果不足惜辕漂,卻給世界環(huán)境...
    茶點故事閱讀 40,150評論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望吴超。 院中可真熱鬧钉嘹,春花似錦、人聲如沸鲸阻。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至陈辱,卻和暖如春奖年,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背沛贪。 一陣腳步聲響...
    開封第一講書人閱讀 32,121評論 1 267
  • 我被黑心中介騙來泰國打工拾并, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人鹏浅。 一個月前我還...
    沈念sama閱讀 46,628評論 2 362
  • 正文 我出身青樓,卻偏偏與公主長得像屏歹,于是被迫代替她去往敵國和親隐砸。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,724評論 2 351