
电商项目——分布式事务——第十三章——中篇
3:假失败情况:调用远程库存服务,库存服务已经锁定成功了,可是由于机器慢,卡死服务器等原因, 我们库存锁成功本地事务提交了以后,一直给他没返回,我们远程调用就有一个超时机制,一判断超时了 我们感知到异常了,感知到的并不是库存锁失败的异常,是读取超时的异常,只要我们感知到了异常,所有的订单都会进行回滚 导致库存锁成功了,可是订单却回滚了
主要就是3,4种情况
所以我们出现了分布式事务 如上代码用到的是本地事务
如下隔离级别由低到高
分布式事务就是保证什么样的一致性来做的
我们最终还是使用消息队列来解决高并发问题
发布日期: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);)异常,由于库存服务是自治的,远程的库存服务自己会回滚, 让后把异常感知到以后,会交给我们的订单服务,订单远程调用以后也会知道库存调用失败,也会回滚通过异常机制。。如下图



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

//本地事务,在分布式系统中,只可以控制住自己回滚,控制不了别人回滚(比如调用远程的ware服务) //分布式事务:最大原因。网络问题
接下来我们讲分布式事务
2:本地事务隔离级别&传播行为等复习
回顾一下本地事务












3:分布式CAP&Raft原理
分布式事务






4:BASE

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






6:Seata&环境准备
7:Seata分布式事务体验
8:最终一致性库存解锁逻辑
我们使用seata的2pc模式会带来很多问题,它适用于一般的分布式事务,不适用于高并发场景

发表评论
最新留言
留言是一种美德,欢迎回访!
[***.207.175.100]2025年04月07日 05时12分01秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
ubuntu学习笔记-常用文件、命令以及作用(hosts、vim、ssh)
2019-03-05
SLAM学习笔记-求解视觉SLAM问题
2019-03-05
普歌-允异团队-HashMap面试题
2019-03-05
还在一个一个手动安装虚拟机吗?Cobbler自动部署装机一键最小化安装打把游戏就好了
2019-03-05
程序员应该知道的97件事
2019-03-05
create-react-app路由的实现原理
2019-03-05
Linux环境变量配置错误导致命令不能使用(杂谈)
2019-03-05
openstack安装(九)网络服务的安装--控制节点
2019-03-05
shell编程(六)语言编码规范之(变量)
2019-03-05
vimscript学习笔记(二)预备知识
2019-03-05
Android数据库
2019-03-05
HTML基础,块级元素/行内元素/行内块元素辨析【2分钟掌握】
2019-03-05
STM8 GPIO模式
2019-03-05
23种设计模式一:单例模式
2019-03-05
Qt中的析构函数
2019-03-05
C语言实现dijkstra(adjacence matrix)
2019-03-05
三层框架+sql server数据库 实战教学-徐新帅-专题视频课程
2019-03-05
【单片机开发】智能小车工程(经验总结)
2019-03-05
【单片机开发】基于stm32的掌上游戏机设计 (项目规划)
2019-03-05