日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

SpringCloud+Seata1.4+Nacos1.4+MySQL8实现分布式事务(客户端)

發(fā)布時(shí)間:2025/3/15 数据库 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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ù)庫
    • seata_order
    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ù):

    • seata_account
    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ù):

    • seata_storage
    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
  • /*** 創(chuàng)建訂單->調(diào)用庫存服務(wù)扣減庫存->調(diào)用賬戶服務(wù)扣減賬戶余額->修改訂單狀態(tài)* 簡(jiǎn)單說:下訂單->扣庫存->減余額->改狀態(tài)*/ @Override //@GlobalTransactional(name = "fsp-create-order",rollbackFor = Exception.class) public void create(Order order) {log.info("----->開始新建訂單");//1 新建訂單orderDao.create(order);//2 扣減庫存log.info("----->訂單微服務(wù)開始調(diào)用庫存,做扣減Count");storageService.decrease(order.getProductId(),order.getCount());log.info("----->訂單微服務(wù)開始調(diào)用庫存,做扣減end");//3 扣減賬戶log.info("----->訂單微服務(wù)開始調(diào)用賬戶,做扣減Money");accountService.decrease(order.getUserId(),order.getMoney());log.info("----->訂單微服務(wù)開始調(diào)用賬戶,做扣減end");//4 修改訂單狀態(tài),從零到1,1代表已經(jīng)完成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中扣減賬戶余額開始");//模擬超時(shí)異常,全局事務(wù)回滾//暫停幾秒鐘線程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ù)
  • /*** 創(chuàng)建訂單->調(diào)用庫存服務(wù)扣減庫存->調(diào)用賬戶服務(wù)扣減賬戶余額->修改訂單狀態(tài)* 簡(jiǎn)單說:下訂單->扣庫存->減余額->改狀態(tài)*/@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ò),歡迎將生活随笔推薦給好友。