Java生鲜电商平台-OMS订单系统中并发问题和锁机制的探讨与解决方案

说明:Java开源生鲜电商中OMS订单系统中并发问题和锁机制的探讨与解决方案:

问题由来

    假设在一个订单系统中(以火车票订单系统为例),用户A,用户B都要预定从成都到北京的火车票,A、B在不同的售票窗口均同时查询到了某车厢卧铺中、下铺位有空位。用户A正在犹豫订中铺还是下铺,这时用户B果断订购了下铺。当用户A决定订下铺时,系统提示下铺已经被预订,请重新选择铺位。在这个系统场景中,我们来探讨一下,火车票系统是怎样处理并发事件以及怎么利用锁机制来避免重复订票的。

设想的方案

方案1:

为了避免重复订票,大部分人会想到在做订票操作前,去数据库查询该铺位是否已经被预订,假设“铺位”数据库表增加标记字段FLAG(空闲:0;已预订:1),如果查询到铺位的FLAG字段值为1,那么预订就不成功,如果为0就成功预订,并把FLAG置为1。这种方案如果在业务量很少的系统中,或许可行。但业务量较大时,特别是火车票这样的业务量,就会出现问题。问题在,当用户A、用户B同时对同一铺位预订时,虽说是“同时”,但对于数据库操作来说一定是有先后顺序的,假设A在查询该铺位的FLAG时,值为0,准备预订并将值设为1,而与此同时B已经预订成功,并已将FLAG设为1。而A因为没有即时查询到FLAG=1,因此也预订成功,又将FLAG设为1。

A      FLAG=0      时刻=T1   (查询)

B      FLAG=0      时刻=T2   (查询)

B      FLAG=1      时刻=T3   (更新)

A      FLAG=1      时刻=T4   (更新)

这样就造成了重复订票,在购票高峰期,使用这样的方案,重复订票不可避免。

方案2:

我们想到了利用数据库的悲观锁来解决这个问题,设想假如用户A查询到想预订的票,用户B根本都查询不到,只有A一个人能看到,那是不是没有重复订票的可能了,因为压根没人跟他抢。可以这样实现这个方案:

select * from table where …… for update skip locked,该语句是查询用户指定条件的票信息,并加锁(for update),如果有记录已经被锁则自动跳到下一条记录(skip locked),这样谁先查询谁就可以慢慢的考虑要上铺还是下铺。但火车票系统是这样做的吗?显然不是,因为这样用户体验太不好,票实际还很多,但确看不到买不到,这显然不合理。

方案3:

我们又想到了从程序层面来解决并发问题,最简便的方式是利用synchronized来处理,但我们要知道一个大型系统必然是集群方式部署的,synchronized只能解决单节点环境的并发问题,要解决此问题还是必须依赖全局性的锁机制。

方案4:

既然又回到了在数据库上加锁,我们又想一下如果我们在查询时,使用乐观锁,但在预订之前使用悲观锁会怎样呢?例如我们查询时:

select * from table where ……

用户A、用户B都查询到了相同的票信息(中铺和下铺),用户A或用户B在预订时做一次悲观锁:

select * from table where …… for update(只对预订的票做悲观锁)

此时后者在预订时,无法获取该记录的锁,自然就无法预订,避免了重复预订的问题。

Java生鲜电商平台-OMS订单系统中并发问题和锁机制的探讨与解决方案的更多相关文章

  1. Java生鲜电商平台-商家支付系统与对账系统架构实战

    Java生鲜电商平台-商家支付系统与对账系统架构实战 说明:关于生鲜电商平台,支付系统是连接消费者.商家(或平台)和金融机构的桥梁,管理支付数据,调用第三方支付平台接口,记录支付信息(对应订单号,支付 ...

  2. Java生鲜电商平台-深入订单拆单架构与实战

    Java生鲜电商平台-深入订单拆单架构与实战 Java生鲜电商中在做拆单的需求,细思极恐,思考越深入,就会发现里面涉及的东西越来越多,要想做好订单拆单的功能,还是相当有难度, 因此总结了一下拆单功能细 ...

  3. Java生鲜电商平台-会员积分系统的设计与架构

    Java生鲜电商平台-会员积分系统的设计与架构 说明:互联网平台积分体系主要用于激励和回馈用户在平台的消费行为和活动行为,一个良好的积分体系可以很好的提升用户的粘性及活跃度. 一.互联网平台积分体系设 ...

  4. Java生鲜电商平台-电商订单系统全解析

    Java生鲜电商平台-电商订单系统全解析 说明:Java生鲜电商平台-电商订单系统全解析主要讲解OMS的内容,设计,开发,架构等知识. 今天分享将会分为以下三个环节来阐述: 1.订单系统的介绍 2.订 ...

  5. Java生鲜电商平台-生鲜系统中商品订单系统售后系统设计

    Java生鲜电商平台-生鲜系统中商品订单系统售后系统设计(服务订单履约系统) 说明: 电商之下,我们几乎能从电商平台上买到任何我们日常需要的商品,但是对于很多商品来说,用户购买发货后,只是整个交易流程 ...

  6. Java生鲜电商平台-生鲜售后系统的退款架构设计与代码分享

    Java生鲜电商平台-生鲜售后系统的退款架构设计与代码分享 说明:任何一个电商行业都涉及到退货与退款的问题,但是生鲜电商行业还设有一个显著的特点,那就是换货.在人性面前,各种各样的退货,退款,换货的售 ...

  7. Java生鲜电商平台-生鲜系统中微服务架构设计与分析实战

    Java生鲜电商平台-生鲜系统中微服务架构设计与分析实战 说明: Java生鲜系统中微服务的拆分应该如何架构设计与分析呢?以下是我的实战中的设计与经验分析. 目录 1. 微服务简介2. 当前现状3. ...

  8. Java生鲜电商平台-系统异常状态的设计与架构(APP应用或者生鲜小程序)

    Java生鲜电商平台-系统异常状态的设计与架构 说明:在实际开发Java生鲜电商平台的时候,异常状态的设计关系着整体系统的性能问题,架构设计,以及稳定性方面,对此,我根据实际的业务场景,进行了系统设计 ...

  9. Java生鲜电商平台-商城系统库存问题分析以及产品设计对逻辑/物理删除思考

    Java生鲜电商平台-商城系统库存问题分析以及产品设计对逻辑/物理删除思考 说明:在生鲜电商的库存设计,是后台的重点,也是难点,关乎商品是否存在超卖.商品的库存增加方式倒不难,直接在后台添加即可,而扣 ...

随机推荐

  1. ROS基础-基本概念和简单工具(1)

    1.什么是ROS? Robot operating System ,简单说机器人操作系统,弱耦合的分布式进程框架,通过进程间的消息传递和管理.实现硬件抽象和设备控制. 2.节点(node) node ...

  2. Python 爬虫从入门到进阶之路(四)

    之前的文章我们做了一个简单的例子爬取了百度首页的 html,我们用到的是 urlopen 来打开请求,它是一个特殊的opener(也就是模块帮我们构建好的).但是基本的 urlopen() 方法不支持 ...

  3. 从web到游戏,走出舒适区

    最近很久没有更新博客了,实在太忙.因为在这段时间里我做了一个改变了我现在职业生涯的一个决定,而我现在正在为这个决定而加倍的努力付出. 我认为我还是有必要把这个比较重要的节点记录下来,我也是第一次在自己 ...

  4. 连接SpringBootAdmin 异常 Name or service not known

    环境: 服务器:Linux 客户端:Windows 当客户端连接到SpringBootAdmin的时候,报了如下异常 明明显示可以连接了,但是就是报了客户端INSTANCE DOWN   (down机 ...

  5. PHP strstr 字符串函数

    定义和用法 strstr - 查找字符串的首次出现 版本支持 PHP4 PHP5 PHP7 支持 支持 支持 V5.3.0 新增可选的 before_needle 参数. V4.3.0 strstr( ...

  6. Python 第一個程序

    以默認方式安裝,會將 Python 安裝在目錄 C:\Users\Administrator\AppData\Local\Programs\Python\Python37 下: 有趣的是: 在此目錄下 ...

  7. Java反射01 : 概念、入门示例、用途及注意事项

    1.Java反射定义 本文转载自:https://blog.csdn.net/hanchao5272/article/details/79360452 官方定义如下: Reflection enabl ...

  8. raspberry-gpio-python(树莓派GPIO与Python编程)

    国外的设计接口设计得很棒,包括问题:读脏与防抖,还包括读这个数据提供了两种方式,一种是阻塞等待方式,还有一种是回调函数,前一种是通讯中常用的方式,后一种来自系统架构设计的整体性考虑.这种硬件接口设计的 ...

  9. JS&Jquery基础之窗口对象的关系总结

    1.top    该变更永远指分割窗口最高层次的浏览器窗口.如果计划从分割窗口的最高层次开始执行命令,就可以用top变量.2.opener opener用于在window.open的页面引用执行该wi ...

  10. 当您解开后您从 Internet 上下载的压缩的文件时,文件的修改日期更改为您提取它的日期

    用鼠标右键单击该压缩的文件,然后单击属性. 单击常规选项卡,请单击取消阻止,然后单击确定. 从压缩文件中提取文件.