SpringCloudAliababa中使用最新版的Seata实现分布式事务

news2024/9/9 7:56:13

SpringCloud中使用Seata实现分布式事务

Hello,兄弟们好,我是Feri,最近整理了最新的基于Seata-Server2.0实现分布式事务的demo,希望对你有所帮助,有任何问题,可以随时沟通交流,在成为技术大牛的路上,我们一路前行!

Apache Seata是一款开源的分布式事务解决方案,致力于在微服务架构下提供高性能和简单易用的分布式事务服务
在这里插入图片描述我是使用的Spring Cloud Aliabab实现的微服务,在这里使用的Seata实现的分布式事务
直接使用的官网提供的案例
用户购买商品的业务逻辑。整个业务逻辑由 3 个微服务提供支持:

  • 仓储服务:对给定的商品扣除仓储数量。
  • 订单服务:根据采购需求创建订单。
  • 帐户服务:从用户帐户中扣除余额。
    在这里插入图片描述本篇对应的源代码,请看文章末尾有链接哈
    实现步骤,搞起来!

1.数据库设计

create database db_seatastudy char set 'utf8mb4';
use db_seatastudy;

DROP TABLE IF EXISTS `storage_tbl`;
CREATE TABLE `storage_tbl` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `commodity_code` varchar(255) DEFAULT NULL,
  `count` int(11) DEFAULT 0,
  PRIMARY KEY (`id`),
  UNIQUE KEY (`commodity_code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


DROP TABLE IF EXISTS `order_tbl`;
CREATE TABLE `order_tbl` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` varchar(255) DEFAULT NULL,
  `commodity_code` varchar(255) DEFAULT NULL,
  `count` int(11) DEFAULT 0,
  `money` int(11) DEFAULT 0,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


DROP TABLE IF EXISTS `account_tbl`;
CREATE TABLE `account_tbl` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` varchar(255) DEFAULT NULL,
  `money` int(11) DEFAULT 0,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

2.创建微服务项目

采用Maven的父子工程实现
根项目:SeataStudy
子项目:
ss-common 公共项目模块
ss-server 服务模块,内部包括3个服务(分别为账户服务、库存服务、订单服务)
内部子项目:
ss-account:账户服务
ss-storage:库存服务
ss-order:订单服务
ss-consumer 对外的服务消费,内部包括1个服务(订单接口Api)
内部子项目:
ss-orderapi
项目结构截图:
在这里插入图片描述

3.实现账户服务

实现账户的新增、修改、查询的接口开发
核心代码:

@RestController
@RequestMapping("/server/account/")
public class AccountTblController{
    /**
     * 服务对象
     */
    @Resource
    private AccountTblService service;

    @PostMapping("add")
    public R<String> add(@RequestBody AccountAdd add){
        return service.save(new AccountTbl(add.getUid(),add.getMoney()))?R.ok(""):R.fail("");
    }
    @GetMapping("all")
    public R all(){
        return R.ok(service.list());
    }
    //修改余额
    @PostMapping("update")
    public Integer updateMoney(@RequestBody AccountAdd update){
        return service.updteMoney(update.getUid(),update.getMoney());
    }
}

在这里插入图片描述

4.实现库存服务

实现库存的新增、修改、查询等功能接口
核心代码:

@RestController
@RequestMapping("/server/storage/")
public class StorageTblController{
    /**
     * 服务对象
     */
    @Resource
    private StorageTblService service;

    @PostMapping("add")
    public R add(@RequestBody StorageAdd add){
        return service.save(new StorageTbl(add.getCode(),add.getNum()))?R.ok(""):R.fail("");
    }
    @GetMapping("all")
    public R all(){
        return R.ok(service.list());
    }
    @PostMapping("update")
    public Integer update(@RequestBody StorageAdd update){
        return service.updateCount(update);
    }
}

在这里插入图片描述

5.实现订单服务

实现订单的新增、查询等操作接口
核心代码:

@Service("orderTblService")
public class OrderTblServiceImpl implements OrderTblService {
    @Resource
    private OrderTblDao dao;
    @Resource
    private AccountService accountService;
    @Resource
    private StorageService storageService;
    
    @Override
    public R<String> add(OrderAdd add) {
        //下单 生成订单 扣款-账户 修改库存-库存
        //1.生成订单
        OrderTbl order=new OrderTbl();
        BeanUtils.copyProperties(add,order);
        dao.insert(order);
        //2.账户 扣款 调用账户服务
        accountService.updateMoney(new AccountAdd(add.getUserId(),-add.getMoney()));
        //3.库存  更改库存
        storageService.update(new StorageAdd(add.getCommodityCode(),-add.getCount()));

        return R.ok("下单成功");
    }

    @Override
    public R<OrderTbl> queryAll(Integer uid) {
        LambdaQueryWrapper<OrderTbl> wrapper=new LambdaQueryWrapper<>();
        if(uid!=null && uid>0){
            wrapper.eq(OrderTbl::getUserId,uid);
        }
        return R.ok(dao.selectList(wrapper));
    }
}


在这里插入图片描述

6.安装和启动Seata-Server

因为Seata需要Seata-server的管理,所以还需要安装一下Seata-server
第一步:下载seata-server
官网提供的Seata-server下载地址,如果下载不了,可以使用我网盘里面的

网盘地址-最新的Seata-Server2.0,点击下载

启动Seata-server
在bin/seata-server.bat 双击启动即可
在这里插入图片描述浏览器访问:http://localhost:7091/
会让输入账号和密码,默认的账号:seata,默认的密码:seata
在这里插入图片描述
在这里插入图片描述

7.项目中使用Seata

需要在项目中使用Seata实现分布式事务,保证下单接口操作的完整性

第一步:依赖jar
在ss-server项目中实现依赖

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>

第二步:在订单服务的下单方法上开启分布式事务
在ss-order的service.impl的add方法上使用注解

@GlobalTransactional
    @Override
    public R<String> add(OrderAdd add) {
        //下单 生成订单 扣款-账户 修改库存-库存
        //1.生成订单
        OrderTbl order=new OrderTbl();
        BeanUtils.copyProperties(add,order);
        dao.insert(order);
        //2.账户 扣款 调用账户服务
        accountService.updateMoney(new AccountAdd(add.getUserId(),-add.getMoney()));
        //3.库存  更改库存
        storageService.update(new StorageAdd(add.getCommodityCode(),-add.getCount()));

        return R.ok("下单成功");
    }

8.测试下单,观察分布式事务的效果

观察,如果某个服务出问题,那么其他会不会回滚
如果会,那么就说明分布式事务生效
在这里插入图片描述
为了演示事务,最好模拟一下出错,比如我这里:

  @Override
    public Integer updateCount(StorageAdd update) {
        System.err.println(1/0);//模拟出错
        return getBaseMapper().updateCount(update.getNum(),update.getCode());
    }

好了,就到这了,你get到了吗?
点击,查看对应的源代码

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1963628.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何处理selenium Webdriver中的文本框?

文本框或字段在整个网页中广泛使用,本文将介绍如何在Java中使用Selenium Webdriver处理文本框。可以有各种文本字段,我们将尝试包括其中的大多数,并执行各种操作,如清除和输入文本。 我们将使用我们的Selenium游乐场网站- testkru,与各种文本框进行交互。您也可以使用同一…

昇思25天学习打卡营第27天|munger85

Vision Transformer图像分类 Vit是最新的用了transformer架构的图像模型&#xff0c;在很多比赛都获得了大奖&#xff0c;是非常优秀的架构。而且据说cnn其实只是vit的一个子集&#xff0c;cnn的卷积其实就是vit在很小的范围做了注意力机制。非常有意思 整个架构就好像这样 图…

七天打造一套量化交易系统:Day6-人工智能在量化投资中的应用

七天打造一套量化交易系统&#xff1a;Day6-人工智能在量化投资中的应用 步骤一&#xff1a;数据获取步骤二&#xff1a;对股票样本进行初步处理步骤三&#xff1a;遗传算法选股遗传算 kmeans 类的主要代码 步骤四&#xff1a;回测结果 遗传算法是一种基础的人工智能算法&#…

springboot惠农服务平台-计算机毕业设计源码50601

目录 1 绪论 1.1 研究背景 1.2研究意义 1.3论文结构与章节安排 2 惠农服务平台app 系统分析 2.1 可行性分析 2.2 系统功能分析 2.3 系统用例分析 2.4 系统流程分析 2.5本章小结 3 惠农服务平台app 总体设计 3.1 系统功能模块设计 3.2 数据库设计 表access_token (…

成品库存周转率报表(一)

文章目录 成品库存周转率报表(一)每日库存结存到表单《历史库存信息》报表逻辑报表设计过滤框简单账表界面存储过程,根据传入条件获取并计算返回数据报表服务插件简单账表绑定数据源插件绑定权限,发布,授权即可访问成品库存周转率报表(一) 每日库存结存到表单《历史库存…

基于域名的虚拟主机,基于ip的域名主机,综合项目eleme

查看nginx配置文件 不看空行&#xff0c;不看注释&#xff0c;查找 [rootstaticserver ~]# grep -Ev "#|^$" /usr/local/nginx/conf/nginx.conf 把原有的文件备份 [rootstaticserver ~]# cp /usr/local/nginx/conf/nginx.conf /usr/local/nginx/conf/nginx.conf.…

虚拟化数据恢复—XenServer VPS不可用如何恢复数据?

虚拟化数据恢复环境&#xff1a; 某品牌R720服务器&#xff0c;4块STAT硬盘通过H710P阵列卡组建了一组raid10磁盘阵列。服务器上部署XenServer虚拟化平台&#xff0c;虚拟机安装Windows Server系统&#xff0c;作为Web服务器使用&#xff0c;运行SQL Server数据库。共有2个虚拟…

智能巡航,守护蓝天绿水:无人机视频技术如何高效监督非法排污行为

随着工业化进程的加速和环境保护意识的日益增强&#xff0c;非法排污行为成为了威胁生态环境、影响公众健康的重大问题。传统的排污监测手段往往受限于人力成本、覆盖范围及效率等因素&#xff0c;难以实现对广袤区域和隐蔽排污点的有效监控。而无人机技术的飞速发展&#xff0…

【网络协议】HTTP协议详解

文章目录 一、概念 二、简史 三、特点 四、工作流程 五、使用Wireshark抓TCP、http包 六、头域 6.1、请求信息&#xff1a; 6.2、请求方法 6.3、响应消息 6.4、响应头域 6.5、HTTP常见的请求头 6.6、HTTP常见的响应头 七、解决HTTP无状态的问题 7.1、通过Cookies保存状态信息 7…

软件性能测试内容和方法揭秘,专业第三方软件测试公司推荐

在数字经济迅猛发展的背景下&#xff0c;软件的性能已经成为企业竞争力的重要一环。性能测试&#xff0c;作为软件测试的一个重要组成部分&#xff0c;主要用于评估应用程序在特定负载下的表现。这不仅包括响应时间、吞吐量、资源使用率等指标&#xff0c;还涉及系统在不同条件…

Stable Diffusion教程|快速入门SD绘画原理与安装

什么是Stable Diffusion&#xff0c;什么是炼丹师&#xff1f;根据市场研究机构预测&#xff0c;到2025年全球AI绘画市场规模将达到100亿美元&#xff0c;其中Stable Diffusion&#xff08;简称SD&#xff09;作为一种先进的图像生成技术之一&#xff0c;市场份额也在不断增长&…

前端-05-VSCode自定义代码片段console.log(js/ts配置)、代码段快捷提示放在首位

目录 配置VSCode自定义代码片段console.log()log代码段快捷提示放在首位 配置VSCode自定义代码片段console.log() 点击VSCode左下角设置图标&#xff0c;点击用户代码片段 点击用户代码片段后&#xff0c;VSCode上方出现弹窗如下图&#xff08;没有显示这两个文件的话搜索一下…

探索国际TikTok矩阵:快速涨粉与变现的全新玩法

在当前的TikTok&#xff08;国际版抖音&#xff09;生态中&#xff0c;矩阵玩法正在成为越来越多内容创作者和电商卖家的热门选择。要有效利用TikTok矩阵&#xff0c;首先得清晰地确定每个账号的内容定位&#xff0c;选择你想要深入的领域。 一、热门TikTok账号类型解析 1. 流量…

milvus - VectorDBBench benchmaker 性能测试工具使用经验

IVF_FLAT (Inverted File with Flat Indexing) 优点: 在数据量适中且维度不是非常高的情况下&#xff0c;IVF_FLAT能提供精确的最近邻搜索结果。 相对简单&#xff0c;易于理解和实现。 缺点: 当数据集非常大时&#xff0c;IVF_FLAT需要大量的内存来存储整个数据集&#xff0c;…

基于欧氏距离的点云聚类(python)

1、背景介绍 欧式聚类是一种基于欧氏距离度量的聚类算法。它是点云处理中的一个重要步骤&#xff0c;它可以帮助我们从无序的点云数据中提取有意义的信息。一般来说&#xff0c;对点云进行欧式聚类处理&#xff0c;可以帮助后续数据处理&#xff0c;如物体检测与识别、三维重建…

链式栈,队列与树形结构

链式栈 链式存储的栈 实现方式&#xff1a;可以使用单向链表完成 对单向链表进行头插&#xff08;入栈&#xff09;、头删&#xff08;出栈&#xff09;&#xff0c;此时链表的头部就是链栈的栈顶&#xff0c;链表的尾部&#xff0c;就是链栈的栈底 队列 概念 队列&#…

二叉树算法题(1)

单值二叉树 思路&#xff1a; 若根结点为NULL&#xff0c;则直接返回true若根结点的左右结点存在&#xff0c;且与根结点的值不相等&#xff0c;则返回false递归根结点的左右子树 typedef struct TreeNode TreeNode; bool isUnivalTree(struct TreeNode* root) {if(root NU…

程序员修炼之路:深入广泛的必修课程

成为一名优秀的程序员&#xff0c;需要广泛而深入地学习多个领域的知识。这些课程不仅帮助建立扎实的编程基础&#xff0c;还培养了问题解决、算法设计、系统思维等多方面的能力。以下是一些核心的必修课&#xff1a; 计算机基础 计算机组成原理&#xff1a;理解计算机的硬件组…

一步步揭秘:浏览器输入URL后的那些事儿

Hello大家好,我是小米,一个热爱分享技术的IT达人。今天我们一起来聊聊一个大家每天都会用到但可能不太了解的过程:浏览器输入URL之后发生了什么。这是一个从用户输入到浏览器显示页面的完整过程,涉及到很多底层的网络基础知识。今天我们就一起来探究这个神秘的过程! DNS解…

Java 中的File类

路径分为绝对路径和相对路径。 相对路径肯定是相对谁来说的&#xff0c;一般是一个文件相对于另外一个文件而言的路径。 下面是一个例子&#xff0c;比如index.htm如何找到photo.jpg呢&#xff1f; c:/website/web/index.htmc:/website/img/photo.jpg 所以在index.htm中使用…