dapeng-soa分布式事務(wù)設(shè)計

1羡疗、基本概念

TI:Transaction Interceptor,事務(wù)攔截器别洪,位于dapeng容器的filterChain鏈中叨恨。

由于TI的邏輯會比較復(fù)雜, 不太適合在IO線程中操作

TM:Transaction Manager, 事務(wù)管理器挖垛,作為一個獨(dú)立的服務(wù)存在痒钝。

事務(wù)發(fā)起方: 服務(wù)調(diào)用鏈或者說請求會話中第一個加入全局事務(wù)的接口方法,稱為事務(wù)發(fā)起方痢毒。
事務(wù)參與方: 服務(wù)調(diào)用鏈或者說請求會話中除事務(wù)發(fā)起方的其它加入了全局事務(wù)的接口方法送矩,稱為事務(wù)參與方。

例如闸准,對于服務(wù)a益愈,b,c, d:
client調(diào)用a.m1, a.m1調(diào)用b.m2以及c.m3, b.m2調(diào)用d.m4.
其中夷家,a.m1以及b.m2,d.m4都聲明為TCC事務(wù)蒸其, 那么在這次服務(wù)調(diào)用中, a.m1為事務(wù)發(fā)起方库快,b.m2,d.m4為事務(wù)參與方摸袁。

由事務(wù)參與方發(fā)起confirm或者cancel操作。

事務(wù)管理器負(fù)責(zé)confirm或者cancel失敗后的重試义屏。

在定義接口的時候靠汁, 需要加上以下注解,以表明該接口需要加入全局事務(wù)闽铐。
@TCC(confirm="",cancel="")
該注解有2個可選參數(shù)蝶怔, 其中, confirm代表該接口的confirm方法名字兄墅,cancel代表該接口的cancel方法名字踢星。

默認(rèn)情況下,methodA的confirm方法名為methodA_confirm, cancel方法名為methodA_cancel

2隙咸、數(shù)據(jù)表結(jié)構(gòu)

t_gtx

CREATE TABLE IF NOT EXISTS `gtx_db`.`t_gtx` (
  `id` INT(11) NOT NULL,
  `gtx_id` INT(11) NOT NULL COMMENT '全局事務(wù)id沐悦,一般使用服務(wù)的會話id(sesstionTid)',
  `status` SMALLINT(2) NOT NULL DEFAULT 1 COMMENT '全局事務(wù)狀態(tài), 1:新建(CREATED);2:成功(SUCCEED);3:失敗(FAILED);4:完成(DONE)',
  `created_time` DATETIME(0) NOT NULL COMMENT '創(chuàng)建時間',
  `updated_time` TIMESTAMP(0) NOT NULL DEFAULT DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '更新時間',
  `remark` VARCHAR(45) NULL COMMENT '備注, 每次狀態(tài)變更都需要追加到remark字段成洗。',
  PRIMARY KEY (`id`),
  INDEX `index_gtx_id` (`gtx_id` ASC))
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8mb4
COMMENT = '全局事務(wù)表'

t_gtx_step

CREATE TABLE IF NOT EXISTS `gtx_db`.`t_gtx_step` (
  `id` INT NOT NULL,
  `gtx_id` INT(11) NOT NULL COMMENT '全局事務(wù)id,一般使用服務(wù)的會話id(sesstionTid)',
  `step_seq` SMALLINT(2) NOT NULL COMMENT '子事務(wù)序號',
  `status` SMALLINT(2) NOT NULL DEFAULT 1 COMMENT '子事務(wù)狀態(tài), 1:新建(CREATED);2:成功(SUCCEED);3:失敗(FAILED);4:完成(DONE)',
  `service_name` VARCHAR(128) NOT NULL COMMENT '服務(wù)名',
  `version` VARCHAR(32) NOT NULL DEFAULT '1.0.0' COMMENT '服務(wù)版本號',
  `method_name` VARCHAR(32) NOT NULL,
  `request` BLOB NULL,
  `confirm_method_name` VARCHAR(32) NULL,
  `cancel_method_name` VARCHAR(32) NULL,
  `redo_times` INT(11) NOT NULL DEFAULT 0,
  `created_time` DATETIME(0) NOT NULL COMMENT '創(chuàng)建時間',
  `updated_time` TIMESTAMP(0) NOT NULL DEFAULT DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '更新時間',
  `remark` VARCHAR(45) NOT NULL DEFAULT '' COMMENT '備注, 每次狀態(tài)變更都需要追加到remark字段藏否。',
  PRIMARY KEY (`id`)),
  INDEX `index_gtx_id` (`gtx_id` ASC))
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8mb4
COMMENT = '全局事務(wù)流程表'

t_gtx_journal
對于參與分布式事務(wù)的服務(wù)接口瓶殃,需要在本地有個事務(wù)流水表(例如orderDb):

CREATE TABLE IF NOT EXISTS `order_db`.`t_gtx_journal` (
  `id` INT(11) NOT NULL,
  `gtx_id` INT(11) NOT NULL COMMENT '全局事務(wù)id',
  `step_id` INT(11) NOT NULL COMMENT '子事務(wù)id',
  `biz_tag` VARCHAR(45) NOT NULL COMMENT '本次全局事務(wù)操作的本地業(yè)務(wù)表名字',
  `biz_id` INT(11) NOT NULL COMMENT '本次全局事務(wù)操作的本地業(yè)務(wù)記錄id',
  `created_time` DATETIME(0) NOT NULL COMMENT '創(chuàng)建時間',
  `updated_time` TIMESTAMP(0) NOT NULL DEFAULT DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '更新時間',
  `remark` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '備注, 每次狀態(tài)變更都需要追加到remark字段。',
  PRIMARY KEY (`id`))
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8mb4
COMMENT = '子事務(wù)的本地流' /* comment truncated */ /*水表副签。 當(dāng)本地事務(wù)成功時遥椿, 由本地業(yè)務(wù)*/

3、案例描述

這里以訂單創(chuàng)建為例继薛。
用戶創(chuàng)建訂單修壕,同時扣除庫存。
其中訂單遏考、庫存分別為兩個不同的服務(wù)慈鸠。同時, TM也是一個單獨(dú)的服務(wù)灌具。

本流程有2個業(yè)務(wù)服務(wù)參與青团,分別是訂單服務(wù)的創(chuàng)建訂單接口以及庫存服務(wù)的庫存扣減接口。

業(yè)務(wù)主流程如下:
1咖楣、客戶端調(diào)用orderService.createOrder, 發(fā)起訂單創(chuàng)建流程
2督笆、orderService調(diào)用stockService.decreaseStock, 扣減庫存
3、orderService創(chuàng)建訂單诱贿,并返回客戶端娃肿。

對應(yīng)的訂單創(chuàng)建序列圖如下:


創(chuàng)建訂單

3.1. 客戶端發(fā)起訂單創(chuàng)建的操作

對應(yīng)時序圖的No.1調(diào)用

參數(shù)

3.2、全局事務(wù)的Try階段

訂單服務(wù)的全局事務(wù)攔截器(TI)收到請求后珠十, 識別到目標(biāo)方法帶有TCC標(biāo)識料扰,即進(jìn)入Trying階段。

3.2.1焙蹭、訂單服務(wù)開啟全局事務(wù)

TI向事務(wù)管理服務(wù)請求開啟全局事務(wù)晒杈,對應(yīng)時序圖的No.2。
tm.beginGTX(gtxId, params)

txId可用sessionTid(long的形式)孔厉,params可直接用bytes

3.2.2拯钻、事務(wù)管理器處理訂單服務(wù)請求

對應(yīng)時序圖的No.3/4/5

事務(wù)管理器根據(jù)txId去決定調(diào)用方是事務(wù)發(fā)起者還是事務(wù)參與者。
這里撰豺,orderService是事務(wù)發(fā)起方粪般, 那么:
1、TM首先通過createTGX(txId)方法創(chuàng)建一個全局事務(wù)(插入一條全局事務(wù)記錄到t_gtx表中,狀態(tài)為新建)
2污桦、通過createStep(txId, params)方法創(chuàng)建一個子事務(wù)日志(插入一條子事務(wù)記錄到t_gtx_step表中亩歹, 狀態(tài)為新建)

全局事務(wù)開啟, 操作成功后返回stepId繼續(xù)下一步,否則失敗后直接返回調(diào)用方捆憎,由調(diào)用方?jīng)Q定是繼續(xù)還是回滾(在這個案例中, 這里的調(diào)用方是client)梭纹。

3.2.3躲惰、訂單服務(wù)的TI轉(zhuǎn)發(fā)請求到具體的業(yè)務(wù)服務(wù)方法

對應(yīng)時序圖中的No.6/7
全局事務(wù)開啟成功后, TI轉(zhuǎn)發(fā)請求到業(yè)務(wù)服務(wù)变抽。這里為orderService.createOrder础拨。

在這個方法中, 首先調(diào)用庫存服務(wù)的扣減庫存接口:stockService.decreaseStock

如果全局事務(wù)開啟失敗绍载,那么TI會直接報錯返回給調(diào)用方(Err-Gtx-001: begin gtx error)

3.2.4诡宗、庫存服務(wù)開啟全局事務(wù)

對應(yīng)時序圖的No.8

同3.2.1,庫存服務(wù)的TI收到扣減庫存請求后击儡,開啟全局事務(wù): `tm.beginGTX'

3.2.5塔沃、事務(wù)管理器處理庫存服務(wù)請求

對應(yīng)時序圖的No.9/10

事務(wù)管理器通過gtxId發(fā)現(xiàn)全局事務(wù)已經(jīng)開啟,那么該請求來自事務(wù)參與方而不是發(fā)起方阳谍。
這時候蛀柴,直接通過createStep插入一條子事務(wù)日志到t_gtx_step表中即可,并返回stepId矫夯。

3.2.6鸽疾、庫存服務(wù)本地邏輯處理

對應(yīng)時序圖的No.11/12/13

TI開始全局事務(wù)成功后, 轉(zhuǎn)發(fā)扣減庫存請求給具體的業(yè)務(wù)方法训貌。
庫存服務(wù)執(zhí)行本地事務(wù)(庫存余額扣減制肮,凍結(jié)庫存增加)后返回到TI

3.2.7、庫存服務(wù)的TI更新全局事務(wù)

對應(yīng)時序圖的No.14/15/16

TI根據(jù)3.2.6的結(jié)果递沪,調(diào)用tm.updateGTX更新全局事務(wù)豺鼻。

TM根據(jù)gtxId以及stepId判斷該請求來自事務(wù)參與方,那么僅更新子事務(wù)日志表updateStep, 狀態(tài)為成功/失敗区拳。

這一步有可能失敗拘领,導(dǎo)致本地子事務(wù)提交后,結(jié)果沒反映到TM的子事務(wù)表的狀態(tài)中樱调。

還有一個可能就是本地子事務(wù)成功约素,TI更新全局事務(wù)也成功了, 但是由于網(wǎng)絡(luò)中斷或者其他原因笆凌,導(dǎo)致服務(wù)調(diào)用方(這里是orderService)的對扣減庫存調(diào)用失敗圣猎。

不管如何,服務(wù)調(diào)用方調(diào)用失敗后乞而,由服務(wù)調(diào)用方自行決定是繼續(xù)前行還是回滾全局事務(wù)送悔。

3.2.8、訂單服務(wù)本地業(yè)務(wù)邏輯處理

對應(yīng)時序圖的No.18/19

訂單服務(wù)根據(jù)庫存扣減的結(jié)果,決定是繼續(xù)往前走還是失敗回退欠啤。

如果繼續(xù)往前走的話荚藻,就完成本地事務(wù)后返回結(jié)果給訂單服務(wù)的TI;
如果失敗回退的話洁段,就把失敗信息返回給訂單服務(wù)的TI应狱。

3.2.9、訂單服務(wù)的TI更新全局事務(wù)

對應(yīng)序列圖的No.20/21/22/23

如果訂單服務(wù)本地事務(wù)成功祠丝,那么TI通過tm.updateGTX把結(jié)果反饋給TM疾呻。

TM根據(jù)gtxId判斷該請求來自事務(wù)發(fā)起方,那么根據(jù)status把全局事務(wù)狀態(tài)更新為成功/失斝窗搿岸蜗;
同時, 更新子事務(wù)狀態(tài)為成功/失敗

全局事務(wù)的最終狀態(tài)跟事務(wù)發(fā)起方對應(yīng)的子事務(wù)的最終狀態(tài)一致叠蝇。

至此璃岳,Trying階段完成。

根據(jù)本階段的結(jié)果蟆肆, TI將會進(jìn)入TCC的confirm(成功)或者cancel階段(失敗)

3.3矾睦、confirm階段

對應(yīng)序列圖的No.24~33
理論上, Trying階段成功的話炎功,confirm階段一定能成功(最終一致).

Confirm操作由TI發(fā)起枚冗,而具體的邏輯由TM控制。

3.3.1 事務(wù)管理器的confirm操作

首先事務(wù)管理器根據(jù)gtxId得到全局事務(wù)記錄以及子事務(wù)記錄集合(gtx_steps)蛇损。

按照子事務(wù)的seq從小到大的順序赁温,依次調(diào)用子事務(wù)的confirm方法。(這個過程可以使用異步的方式并發(fā)去confirm?)

最后根據(jù)結(jié)果更新全局事務(wù)以及子事務(wù)的狀態(tài)淤齐。

只有全部子事務(wù)的狀態(tài)為完成股囊,全局事務(wù)狀態(tài)才能更新為完成。

TI發(fā)起confirm操作后更啄,不管本次confirm操作是否成功稚疹, 都返回成功給client。

3.4祭务、cancel階段

對應(yīng)序列圖的No.24~43
本階段跟confirm階段邏輯類似内狗,但是子事務(wù)的執(zhí)行順序相反

TI發(fā)起cancel操作后义锥,不管本次cancel操作是否成功柳沙, 都返回失敗給client。

3.5拌倍、confirm/cancel階段的異常處理

TM通過定時器赂鲤,定時掃描全局事務(wù)日志表中狀態(tài)為非完成的記錄(1分鐘前)噪径,再次執(zhí)行confirm/cancel操作。

4. 業(yè)務(wù)場景

TCC場景:

4.1. 客戶端調(diào)用單獨(dú)的TCC服務(wù)

image.png

4.1.1 正常流程

try成功数初,confirm成功

  1. try階段:
    1.1 t_gtx, t_gtx_step插入事務(wù)日志成功找爱, 狀態(tài)皆為新建
    1.2 tccServiceA本地事務(wù)成功
    1.3 t_gtx, t_gtx_step更新事務(wù)日志成功,狀態(tài)皆為成功
  2. confirm階段
    2.1 TM調(diào)用tccServiceA成功泡孩,更新t_gtx, t_gtx_step成功缴允,狀態(tài)為完成。

try失敗珍德,cancel成功

  1. try階段:
    1.1 t_gtx, t_gtx_step插入事務(wù)日志成功, 狀態(tài)皆為新建
    1.2 tccServiceA本地事務(wù)失敗
    1.3 t_gtx, t_gtx_step更新事務(wù)日志成功矗漾,狀態(tài)皆為失敗
  2. cancel階段
    2.1 TM調(diào)用tccServiceA成功锈候,更新t_gtx, t_gtx_step成功,狀態(tài)為完成敞贡。

4.1.2 異常流程

try成功泵琳,confirm階段或者cancel階段失敗
那么后續(xù)由TM定時任務(wù)繼續(xù)重試。

4.1.3 異常流程

try階段TI插入事務(wù)日志失敗(Err-Gtx-001: begin gtx error)
如果是事務(wù)發(fā)起方(本案例)誊役, 那么TI直接返回Err-Gtx-001获列,本次服務(wù)調(diào)用失敗。
如果是事務(wù)參與方蛔垢, 那么TI直接返回Err-Gtx-001击孩,并最終回到事務(wù)發(fā)起方,本次全局事務(wù)失敗鹏漆,并對已經(jīng)有記錄的子事務(wù)做cancel操作巩梢。

因為這里缺失了分布式事務(wù)的某個子事務(wù)日志記錄,TM無法進(jìn)行confirm或者cancel操作艺玲。

try階段本地事務(wù)成功括蝠,但是TI更新事務(wù)日志失敗(Err-Gtx-002: update gtx error),子事務(wù)的狀態(tài)停留在新建的狀態(tài)
這時候如果是事務(wù)發(fā)起方(本案例)饭聚,那么TI會繼續(xù)走confirm或者cancel的流程忌警。
如果是事務(wù)參與方,把Err-Gtx-002返回秒梳, 事務(wù)發(fā)起方會忽略該錯誤法绵,其對應(yīng)的TI會繼續(xù)走confirm或者cancel的流程。

在confirm或者cancel的邏輯里端幼,TM會把gtxId以及該子事務(wù)id礼烈、狀態(tài)通過cookie傳過來。
如果子事務(wù)狀態(tài)為成功或者失敗婆跑,那么直接執(zhí)行confirm或者cancel邏輯此熬;

如果子事務(wù)狀態(tài)為新建,那么目前尚不清楚到底try階段的本地事務(wù)執(zhí)行了沒。

如果執(zhí)行了犀忱, 那么必然可以通過gtxId募谎,stepId找到在try階段的本地事務(wù)操作過的本地事務(wù)流水記錄,從而確認(rèn)try階段的本地事務(wù)提交情況阴汇,再進(jìn)而決定本次confirm或者cancel該做的操作数冬。

舉個例子, 庫存服務(wù)的扣減庫存接口搀庶。
在try階段拐纱,本地事務(wù)成功,然后TI在更新子事務(wù)狀態(tài)的時候失敗了哥倔,那么該子事務(wù)狀態(tài)為新建秸架。
然后事務(wù)發(fā)起方依然決定做confirm操作,同時庫存服務(wù)扣減庫存接口的confirm方法咆蒿,通過gtxId以及stepId东抹,找到了本地事務(wù)流水記錄,從而可以執(zhí)行confirm操作沃测。

如果在try階段缭黔,本地事務(wù)失敗,然后TI在更新子事務(wù)狀態(tài)的時候也失敗了蒂破,那么該子事務(wù)狀態(tài)為新建馏谨。
然后事務(wù)發(fā)起方依然決定做confirm操作,同時庫存服務(wù)扣減庫存接口的confirm方法附迷,通過gtxId以及stepId田巴,這時候是找不到本地事務(wù)流水記錄的,說明try階段本地事務(wù)失敗挟秤。 那么業(yè)務(wù)可以調(diào)用一下把try以及confirm的邏輯合并起來壹哺,完成本次confirm操作。

4.2. 客戶端先后調(diào)用2個TCC服務(wù)

image.png

這時候, 這兩次服務(wù)調(diào)用分別構(gòu)成一個全局事務(wù)艘刚, 是兩個互不相關(guān)的全局事務(wù)

4.3. 客戶端調(diào)用TCC服務(wù)a管宵,服務(wù)a再調(diào)用TCC服務(wù)b

image.png

4.4. 客戶端調(diào)用TCC服務(wù)a,服務(wù)a再分別調(diào)用TCC服務(wù)b以及TCC服務(wù)c

image.png

4.5. 客戶端調(diào)用TCC服務(wù)a攀甚,服務(wù)a調(diào)用TCC服務(wù)b箩朴,服務(wù)b再調(diào)用TCC服務(wù)c

image.png

5. 異常流程處理

在4.3的業(yè)務(wù)場景中, tccServiceA調(diào)用tccServiceB失敗秋度,

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末炸庞,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子荚斯,更是在濱河造成了極大的恐慌埠居,老刑警劉巖查牌,帶你破解...
    沈念sama閱讀 222,590評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異滥壕,居然都是意外死亡纸颜,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,157評論 3 399
  • 文/潘曉璐 我一進(jìn)店門绎橘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來胁孙,“玉大人,你說我怎么就攤上這事称鳞′探希” “怎么了?”我有些...
    開封第一講書人閱讀 169,301評論 0 362
  • 文/不壞的土叔 我叫張陵冈止,是天一觀的道長法希。 經(jīng)常有香客問我,道長靶瘸,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,078評論 1 300
  • 正文 為了忘掉前任毛肋,我火速辦了婚禮怨咪,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘润匙。我一直安慰自己诗眨,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 69,082評論 6 398
  • 文/花漫 我一把揭開白布孕讳。 她就那樣靜靜地躺著匠楚,像睡著了一般。 火紅的嫁衣襯著肌膚如雪厂财。 梳的紋絲不亂的頭發(fā)上芋簿,一...
    開封第一講書人閱讀 52,682評論 1 312
  • 那天,我揣著相機(jī)與錄音璃饱,去河邊找鬼与斤。 笑死,一個胖子當(dāng)著我的面吹牛荚恶,可吹牛的內(nèi)容都是我干的撩穿。 我是一名探鬼主播,決...
    沈念sama閱讀 41,155評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼谒撼,長吁一口氣:“原來是場噩夢啊……” “哼食寡!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起廓潜,我...
    開封第一講書人閱讀 40,098評論 0 277
  • 序言:老撾萬榮一對情侶失蹤抵皱,失蹤者是張志新(化名)和其女友劉穎善榛,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體叨叙,經(jīng)...
    沈念sama閱讀 46,638評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡锭弊,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,701評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了擂错。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片味滞。...
    茶點故事閱讀 40,852評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖钮呀,靈堂內(nèi)的尸體忽然破棺而出剑鞍,到底是詐尸還是另有隱情,我是刑警寧澤爽醋,帶...
    沈念sama閱讀 36,520評論 5 351
  • 正文 年R本政府宣布蚁署,位于F島的核電站,受9級特大地震影響蚂四,放射性物質(zhì)發(fā)生泄漏光戈。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,181評論 3 335
  • 文/蒙蒙 一遂赠、第九天 我趴在偏房一處隱蔽的房頂上張望久妆。 院中可真熱鬧,春花似錦跷睦、人聲如沸筷弦。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,674評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽烂琴。三九已至,卻和暖如春蜕乡,著一層夾襖步出監(jiān)牢的瞬間奸绷,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,788評論 1 274
  • 我被黑心中介騙來泰國打工层玲, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留健盒,地道東北人。 一個月前我還...
    沈念sama閱讀 49,279評論 3 379
  • 正文 我出身青樓称簿,卻偏偏與公主長得像扣癣,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子憨降,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,851評論 2 361

推薦閱讀更多精彩內(nèi)容

  • 一個TCC事務(wù)框架需要解決的當(dāng)然是分布式事務(wù)的管理父虑。關(guān)于TCC事務(wù)機(jī)制的介紹,可以參考TCC事務(wù)機(jī)制簡介授药。 TCC...
    Java高級進(jìn)階閱讀 1,499評論 0 0
  • 一. 事務(wù) 1.1 什么是事務(wù) 數(shù)據(jù)庫事務(wù)(簡稱:事務(wù)士嚎,Transaction)是指數(shù)據(jù)庫執(zhí)行過程中的一個邏輯單位...
    Java小鋪閱讀 578評論 0 3
  • 為什么無眠呜魄?想要把夜拉長,再拉長一些莱衩! 夜是寫滿悲歡的月色爵嗅,伴隨著不愿迷失的靈魂,怕自己睡下貪戀夢的旖旎笨蚁! 夜是掛...
    馨欣然閱讀 409評論 0 3
  • 時間習(xí)慣書寫故事 在每個地方珍藏一段記憶 然后凝化于心 標(biāo)簽: 原創(chuàng)
    趙藝閎Z閱讀 155評論 0 0