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

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到了吗?
点击,查看对应的源代码

  • 7
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值