首页 > 其他分享 >排队下单生成自增排序号码的问题场景分析

排队下单生成自增排序号码的问题场景分析

时间:2024-12-13 18:11:39浏览次数:6  
标签:自增 加锁 取餐 下单 排序 点单 我们

今天和同事去地铁口下面的一个面店吃饭,大家桌面扫码后下单,发现自己会有一个取餐号,我的是39,同事的是40多。

这当然很容易想到,这个取餐号码是自增的,这种场景再熟悉不过了,在以往我们去饭店吃饭拿到的号因为是在柜台口头下单,服务员扫码支付,所以小票机器打出来的单号就很容易是看的出来自增的,这种生成逻辑就是+1就行了,只有一个地方在点单,这样的逻辑当然没问题。

现在是桌面扫码了,就出现了我们开发最常见也最头疼的问题,并发问题。如果现在的最大取餐号是30,两人同时下单,或者同时支付,怎么保证两人取到的一个是31 一个是32 ,而不是都是31?

假设现在订单表如下:

表格内容如下:

这是 百变机兽之洛洛历险记 的主要角色和人物,我们采用这些人物角色带入他们在餐厅点单的场景。

1号洛洛和2号晶晶已经先下单,拿到游戏,开始体验,我们看到我们应该自动分配出 0001 给洛洛 , 0002 给晶晶,然后其余的机车族战士和猛兽族战士也纷纷下单获得技能卡,各自得到取餐号,现在最大取餐号是0012,下一个应该是0013。

现在金铁兽也要下单,该如何正确的分到这个0013的取餐号码呢?

方案1:

如果按最简单的开发思路,我们获取当前最大的 get_order_number ,将其取出来,然后 +1 ,之后再插入记录,那么程序设计如下:

可以看到我们的代码先是取出最大number,然后对其做00前缀的补齐,之后我们做一个拼接SQL,然后插入数据库,当然实际业务肯定比这个复杂很多,但我们这里简化了模型就用来将现在的自增序号问题。

这是最容易想到的实现方案,但是这个方案必然会有数据并发问题,假如实际情况是现在金铁兽和银铁兽都要下单,那他们都要买极光神风爪技能卡,会不会他们都分到了0013这个编号呢?

答案是显而易见的啊,非常有可能都分到这个号码,那么该如何避免这个问题呢?我们想到是不是可以设定加锁来控制写入呢,由此我们推导出方案2。

方案2

通过加锁(分布式锁 这里以redis为例),能够让代码顺序的执行,我们可以在代码执行之前设定一个变量来加锁判断一下,比如这样:

 这里我们对这个当前点单的1号店铺进行设置key并加锁判断,只有拿到锁的人才能进行点单,才能走下一步,那么显然问题出现了,这样别人就得等了,这就是阻塞住了,等于程序上降低了应用可并发的数量。这样也还是有点问题,有没有更好的方法呢?这里我们介绍方案3.

方案3

我们直接使用 redis incr 方法能对一个数进行自增且返回这个自增后的结果,那不就是我们要的了吗?大道至简啊!

 

标签:自增,加锁,取餐,下单,排序,点单,我们
From: https://www.cnblogs.com/lizhaoyao/p/18605502

相关文章

  • 记一次数据库查询排序不一致导致的事故
    数据库查询排序不一致事故报告1.引言在数据库开发和维护过程中,查询结果的排序一致性是一个关键的需求。然而,近期在我们的招标系统中发生了一起因数据库查询排序不一致而导致的问题,给系统稳定性和用户体验带来了负面影响。本文将详细还原此次事故的过程,分析问题的根本原因,并提出......
  • 三种基本常见的排序算法(冒泡,选择,插入)
    一: 冒泡算法是一种简单的排序算法,以下是关于它的详细介绍: 基本原理: 重复遍历要排序的数列,每次比较相邻的两个元素,如果它们的顺序错误就将它们交换过来,直到整个数列都有序为止。 算法步骤 1: 比较相邻的元素。如果第一个比第二个大,就交换它们两个。2.:对每一......
  • C++实现希尔排序算法
    指定格式输入字母(字母间以空格分隔),按照希尔排序输出指定格式#include<iostream>#include<vector>#include<string>usingnamespacestd;voidshellSort(vector<string>&arr){ intn=arr.size(); //初始步长设置为数组长度的一半,后面逐步缩小步长直到值为1为止 for......
  • 每日一道算法题之拓扑排序之按照最小字典输出
    importjava.io.*;importjava.util.*;publicclassMain{publicstaticintn=100001;publicstaticintm=100001;publicstaticArrayList<ArrayList<Integer>>graph=newArrayList<>();publicstaticPriorityQueue&......
  • 排序算法-希尔排序
    介绍希尔排序也称缩小增量排序,属于插入排序中的一种排序算法,是在插入排序的基础上进行的改进,采用分组策略进行排序。相关特点时间复杂度:最好:O(n)、最坏:O(n2)、平均:O(n1.3)辅助空间复杂度:O(1)稳定性:不稳定排序原理希尔排序通过设定一个初始增量,将数组元素分组进行插入排序......
  • 华为机试HJ101 输入整型数组和排序标识,对其元素按照升序或降序进行排序
    首先看一下题描述输入整型数组和排序标识,对其元素按照升序或降序进行排序数据范围: 1≤n≤1000  ,元素大小满足 0≤val≤100000 输入描述:第一行输入数组元素个数第二行输入待排序的数组,每个数用空格隔开第三行输入一个整数0或1。0代表升序排序,1代表降序排序输出......
  • C语言-排序
    常见的排序算法分为以下四种,插入排序,选择排序,交换排序,归并排序。一、插入排序(一)直接插入排序直接插入排序,将一段数组看做被分成已排序序列和未排序序列,排序过程是从未排序序列的元素开始,该元素与已排序序列的元素从后向前扫描,找到第一个小于(或大于)该元素的已排序项,然后将......
  • 成绩排序
    输入nnn个同学的语文、数学、和英语成绩,计算他们的总分,要求按从高到低的顺序输出总分。【输入格式】第一行:输入1......
  • 递归自增小工具
    最近开发需求遇到一个奇葩需求,用户重复上传文档,需要生成一个副本,比如用户上传了个a.pdf,然后又上传了a.pdf最后一个需要为a-副本.pdf。好了,活干完了,开发找到产品,说要是在原来副本的基础上又上传一个a-副本.pdf,要生成a-副本-副本.pdf吗?产品傻了。我们给产品像个策略。重复的以后缀......
  • 每日一道算法题之拓扑排序之课程表
    importjava.util.ArrayList;importjava.util.Deque;classSolution{publicint[]findOrder(intnumCourses,int[][]prerequisites){//思路:入度为0的点入队。依次出队的时候。遍历当前点的指向。入度减1,//如果入度为0.进队。//队......