电商项目——分布式事务——第十三章——中篇
发布日期:2021-05-07 02:38:26 浏览次数:23 分类:精选文章

本文共 3622 字,大约阅读时间需要 12 分钟。

文章目录

1:本地事务在分布式下的问题

在这里插入图片描述

@Transactional    @Override    public SubmitOrderResponseVo submitOrder(OrderSubmitVo vo) {           confirmVoThreadLocal.set(vo);        SubmitOrderResponseVo submitOrderResponseVo=new SubmitOrderResponseVo();        //使用拦截器里面的threalocal        MemberRespVo memberRespVo = OrderInterceptor.loginUser.get();        //1:验证令牌【令牌的对比和删除,获取令牌必须保证原子性】        //如果redis调用get方法获取KEYS[1]值,然后它就会返回令牌删除,然后返回0        //0令牌对比不一样就删除失败 1令牌对比删除成功        String script="if redis.call('get',KEYS[1]) == ARGV[1] then return redis.call('del',KEYS[1]) else return 0 end";        String orderToken = vo.getOrderToken();        //原子令牌验证和删除        Long result = redisTemplate.execute(new DefaultRedisScript
(script, Long.class), Arrays.asList(OrderConstant.USER_ORDER_TOKEN_PREFIX + memberRespVo.getId()), orderToken); if (result==0){ //令牌验证不通过 submitOrderResponseVo.setCode(1); return submitOrderResponseVo; }else { //令牌验证通过// 下单:去创建订单,验证令牌,验证价格,锁库存 //第一步:创建订单,订单项等信息 OrderCreateTo order=createOrder(); //第二步:验证价格 BigDecimal payAmount = order.getOrder().getPayAmount(); BigDecimal payPrice = vo.getPayPrice(); //前端传来的页面的值和后端我们计算的价格这两个值相差不可以大于0.1;;就是会有误差很正常 if (Math.abs(payAmount.subtract(payPrice).doubleValue())<0.1){ //金额对比.. // todo 第三步:保存订单 saveOrder(order); //todo 第四步:远程库存锁定 我们现在要加一个事务(只要有异常回滚订单数据) 只要订单一保存成功,我们马上就要锁住库存,如果库存没锁住就会回调返回失败 //订单号,所有订单项(skuId,skuName,num) WareSkuLockVo lockVo=new WareSkuLockVo(); lockVo.setOrderSn(order.getOrder().getOrderSn()); List
locks = order.getOrderItems().stream().map(item -> { OrderItemVo itemVo = new OrderItemVo(); itemVo.setSkuId(item.getSkuId()); itemVo.setCount(item.getSkuQuantity()); itemVo.setTitle(item.getSkuName()); return itemVo; }).collect(Collectors.toList()); lockVo.setLocks(locks); //去(mall-ware)库存服务锁住我们在mall-order中传递过来的lockVo R r = wareFeignService.orderLockStock(lockVo); if (r.getCode()==0){ //锁成功 submitOrderResponseVo.setOrderEntity(order.getOrder()); //todo 远程扣减积分 return submitOrderResponseVo; }else { //锁失败 throw new NoStockException();// submitOrderResponseVo.setCode(3);// return submitOrderResponseVo; } }else { submitOrderResponseVo.setCode(2); return submitOrderResponseVo; } } }

本地事务在分布式下的问题1:假设订单服务出现异常,根据代码可知,直接回滚,都不会完下面走

本地事务在分布式下的问题2:假设库存服务出现(wmsFeignService.orderLockStock(lockVo);)异常,由于库存服务是自治的,远程的库存服务自己会回滚,
让后把异常感知到以后,会交给我们的订单服务,订单远程调用以后也会知道库存调用失败,也会回滚通过异常机制。。如下图
在这里插入图片描述
在这里插入图片描述
3:假失败情况:调用远程库存服务,库存服务已经锁定成功了,可是由于机器慢,卡死服务器等原因,
我们库存锁成功本地事务提交了以后,一直给他没返回,我们远程调用就有一个超时机制,一判断超时了
我们感知到异常了,感知到的并不是库存锁失败的异常,是读取超时的异常,只要我们感知到了异常,所有的订单都会进行回滚
导致库存锁成功了,可是订单却回滚了
在这里插入图片描述

在这里插入图片描述

第4种情况:如下图片

在这里插入图片描述

在这里插入图片描述
主要就是3,4种情况

如果使用异常机制处理事务回滚(如上面的代码),我们就会出现如下两个问题

在这里插入图片描述
所以我们出现了分布式事务
如上代码用到的是本地事务

//本地事务,在分布式系统中,只可以控制住自己回滚,控制不了别人回滚(比如调用远程的ware服务)    //分布式事务:最大原因。网络问题

接下来我们讲分布式事务

2:本地事务隔离级别&传播行为等复习

回顾一下本地事务

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
如下隔离级别由低到高
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3:分布式CAP&Raft原理

分布式事务

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

4:BASE

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
分布式事务就是保证什么样的一致性来做的

5:分布式事务常见解决方案

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

6:Seata&环境准备

在这里插入图片描述

7:Seata分布式事务体验

在这里插入图片描述

8:最终一致性库存解锁逻辑

我们使用seata的2pc模式会带来很多问题,它适用于一般的分布式事务,不适用于高并发场景

在这里插入图片描述
我们最终还是使用消息队列来解决高并发问题

上一篇:Java后端技术体系-学习顺序总结
下一篇:接口幂等性介绍

发表评论

最新留言

留言是一种美德,欢迎回访!
[***.207.175.100]2025年04月07日 05时12分01秒