生活随笔
收集整理的這篇文章主要介紹了
SpringCloud+Seata1.4+Nacos1.4+MySQL8实现分布式事务(客户端)
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
本文基于,在此基礎(chǔ)上進(jìn)行更深入的探索
一、Seata執(zhí)行流程
TM開啟分布式事務(wù)(TM向TC注冊(cè)全局事務(wù)記錄)按業(yè)務(wù)場(chǎng)景,編排數(shù)據(jù)庫、服務(wù)等事務(wù)內(nèi)資源(RM向TC匯報(bào)資源準(zhǔn)備狀態(tài))TM結(jié)束分布式事務(wù),事務(wù)一階段結(jié)束(TM 通知TC提交/回滾分布式事務(wù)) TC匯總事務(wù)信息,決定分布式事務(wù)是提交還是回滾TC通知所有RM提交/回滾資源,事務(wù)二階段結(jié)束
TC (Transaction Coordinator) - 事務(wù)協(xié)調(diào)者 維護(hù)全局和分支事務(wù)的狀態(tài),驅(qū)動(dòng)全局事務(wù)提交或回滾TM(Transaction Manager) - 事務(wù)管理器 定義全局事務(wù)的范圍:開始全局事務(wù)、提交或回滾全局事務(wù)RM (Resource Manager) - 資源管理器 管理分支事務(wù)處理的資源,與TC交談以注冊(cè)分支事務(wù)和報(bào)告分支事務(wù)的狀態(tài),并驅(qū)動(dòng)分支事務(wù)提交或回滾
搭建Seata1.4+Nacos1.4+MySQL8服務(wù)端
創(chuàng)建三個(gè)微服務(wù),分別為: 訂單服務(wù)、賬戶服務(wù)、庫存服務(wù)
最重要的seata配置用一張圖說明
二、搭建運(yùn)行環(huán)境
建立三個(gè)數(shù)據(jù)庫
CREATE DATABASE seata_order
;CREATE TABLE
`t_order` (`id` bigint
(0
) NOT NULL AUTO_INCREMENT,
`user_id` bigint
(0
) NULL DEFAULT NULL COMMENT
'用戶id',
`product_id` bigint
(0
) NULL DEFAULT NULL COMMENT
'產(chǎn)品id',
`count` int
(0
) NULL DEFAULT NULL COMMENT
'數(shù)量',
`money` decimal
(11, 0
) NULL DEFAULT NULL COMMENT
'金額',
`status` int
(0
) NULL DEFAULT NULL COMMENT
'訂單狀態(tài):0:創(chuàng)建中; 1:已完結(jié)',PRIMARY KEY
(`id`) USING BTREE
) ENGINE
= InnoDB AUTO_INCREMENT
= 12 CHARACTER SET
= utf8 COLLATE
= utf8_general_ci ROW_FORMAT
= Dynamic
;
原始數(shù)據(jù):
CREATE DATABASE seata_account
;CREATE TABLE
`t_account` (`id` bigint
(11
) NOT NULL AUTO_INCREMENT,
`user_id` bigint
(11
) DEFAULT NULL COMMENT
'用戶id',
`total` decimal
(10, 0
) DEFAULT NULL COMMENT
'總額度',
`used` decimal
(10, 0
) DEFAULT NULL COMMENT
'已用余額',
`residue` decimal
(10, 0
) DEFAULT NULL COMMENT
'可用余額',PRIMARY KEY
(`id`) USING BTREE
) ENGINE
= InnoDB AUTO_INCREMENT
= 2 CHARACTER SET
= utf8 COLLATE
= utf8_general_ci ROW_FORMAT
= Dynamic
;
INSERT INTO
`t_account` VALUES
(1, 1, 1000, 0, 1000
);
原始數(shù)據(jù):
CREATE DATABASE seata_storage
;CREATE TABLE
`t_storage` (`id` bigint
(0
) NOT NULL AUTO_INCREMENT,
`product_id` bigint
(0
) NULL DEFAULT NULL COMMENT
'產(chǎn)品id',
`total` int
(0
) NULL DEFAULT NULL COMMENT
'總庫存',
`used` int
(0
) NULL DEFAULT NULL COMMENT
'已用庫存',
`residue` int
(0
) NULL DEFAULT NULL COMMENT
'剩余庫存',PRIMARY KEY
(`id`) USING BTREE
) ENGINE
= InnoDB AUTO_INCREMENT
= 2 CHARACTER SET
= utf8 COLLATE
= utf8_general_ci ROW_FORMAT
= Dynamic
;INSERT INTO
`t_storage` VALUES
(1, 1, 100, 0, 100
);
原始數(shù)據(jù):
然后,在這三個(gè)庫下面各自建一個(gè)undo_log表
官方腳本連接
開啟三個(gè)服務(wù),分別是賬戶服務(wù),訂單服務(wù)和庫存服務(wù),注冊(cè)到nacos
三、測(cè)試
訂單服務(wù)先不開啟全局事務(wù),注釋掉@GlobalTransactional
@Override
public void create(Order order
)
{log
.info("----->開始新建訂單");orderDao
.create(order
);log
.info("----->訂單微服務(wù)開始調(diào)用庫存,做扣減Count");storageService
.decrease(order
.getProductId(),order
.getCount());log
.info("----->訂單微服務(wù)開始調(diào)用庫存,做扣減end");log
.info("----->訂單微服務(wù)開始調(diào)用賬戶,做扣減Money");accountService
.decrease(order
.getUserId(),order
.getMoney());log
.info("----->訂單微服務(wù)開始調(diào)用賬戶,做扣減end");log
.info("----->修改訂單狀態(tài)開始");orderDao
.update(order
.getUserId(),0);log
.info("----->修改訂單狀態(tài)結(jié)束");log
.info("----->下訂單結(jié)束了,O(∩_∩)O哈哈~");
}
賬戶服務(wù)模擬超時(shí)異常
@Overridepublic void decrease(Long userId
, BigDecimal money
) {LOGGER
.info("------->account-service中扣減賬戶余額開始");try { TimeUnit
.SECONDS
.sleep(20); } catch (InterruptedException e
) { e
.printStackTrace(); }accountDao
.decrease(userId
,money
);LOGGER
.info("------->account-service中扣減賬戶余額結(jié)束");}
Postman測(cè)試
t_account表:
t_order表:
t_storage表:
此時(shí)可以看到賬戶和庫存都已經(jīng)減少,訂單已經(jīng)生成,而訂單狀態(tài)卻是未完成,這在生產(chǎn)環(huán)境中是很嚴(yán)重的問題
手動(dòng)還原數(shù)據(jù)后,訂單服務(wù)開啟全局事務(wù)注解@GlobalTransactional,驗(yàn)證分布式事務(wù)
@Override@GlobalTransactional(name
= "fsp-create-order",rollbackFor
= Exception
.class)public void create(Order order
)
Postman測(cè)試
t_account表:
t_order表:
t_storage表:
由上述表數(shù)據(jù)可知分布式事務(wù)驗(yàn)證通過,同時(shí)成功or同時(shí)失敗(所有分支事務(wù)全都回滾)
seata后臺(tái)也顯示成功回滾事務(wù)
四、偽代碼幫助理解
總結(jié)
以上是生活随笔為你收集整理的SpringCloud+Seata1.4+Nacos1.4+MySQL8实现分布式事务(客户端)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。