【问题标题】:How to make sure two users don't get the same roll number?如何确保两个用户没有得到相同的卷号?
【发布时间】:2018-01-22 02:53:13
【问题描述】:

让我告诉你一些关于我的应用程序和问题的信息: 此应用程序将用于 将学生注册到组织推出的特定课程中。除其他信息外,学生将在表格中提供以下信息:

  • 可用课程中的一门课程
  • 他的照片

表格提交成功后,他可以打印准考证。

现在是管理员:

  • 他可以创建任意数量的课程
  • 他可以切换课程的可用性
  • 他可以选择在哪里start课程的卷号
  • 他可以更改课程的current 卷号

学生点击提交后的步骤如下:

  1. 从表格中获取course_id,并获取该课程的current卷号
  2. 将图像以current 卷号作为文件名保存在路径course_name/batch/roll_number.(png|jpg)
  3. 图片保存成功则获取图片,否则拒绝
  4. 调整图片大小并覆盖现有图片,如果调整大小失败则删除图片并拒绝
  5. 将学生的表格保存在forms 集合中
  6. courses 集合中增加该课程的current 卷号
  7. 发送包含表单数据的响应以及图像的 base64 字符串(将用于准考证)

问题:

问题是如果用户几乎同时提交表单,它可能会生成重复的卷号,因为他们将使用相同的current 卷号。 我无法解决这个问题,因为我不能简单地自动增加表单的 roll_number 因为它来自courses 集合。

这是我的数据库的样子:

{   
    "courses":[
        {
            "_id" : ObjectId,
            "batches": [Object],
            "course_name" : String,
            "current": Number, // current roll number
            "start" : Number, // starting roll number
            "available": Boolean
        }
    ],
    "forms": [
        {
            "_id": ObjectId,
            "roll_number": Number,
            "course_id" : ObjectId
            // other stuff
        }
    ],
    "settings": [ // always have one object
        {
            "_id" : ObjectId,
            "accept_form": Boolean,
            "courses": [ObjectId]
        }
    ]
}

我正在使用:

保存图片的multer:https://github.com/expressjs/multer

调整图像大小的锐利:https://github.com/lovell/sharp

处理请求的expressjs

请告诉我应该怎么做才能解决这个重复问题。

【问题讨论】:

  • 将架构中的"current" 定义为unique: true

标签: mongodb express mongoose multer sharp


【解决方案1】:

不幸的是,在 MongoDB 中没有简单的方法可以做到这一点。但是,您可以使用多种策略来确保您的表单集合中不会出现重复的卷号。

首先,确保您在 roll_number 字段上设置了唯一索引。至少 mongo 会在您尝试插入重复值时通知您。

方法#1

创建一个执行以下操作的循环:

  1. 从课程集合中读取当前卷号,并添加到表单对象中
  2. 尝试保存表单对象并检查mongo db是否返回重复错误
  3. 如果卷号已被使用,则增加课程当前号
  4. 重复步骤 1

注意:根据可能同时保存表单的用户数量,上述方法可能会非常详尽。但是对于一个用户数量中等的系统,在同一秒内发生多个表单保存操作的概率应该很小,并且这种方法应该提供可接受的结果。

方法#2

另一种可行但更困难的方法是在保存表单后将卷号分配任务传递给单个后台工作线程。

在 nodeJs 中,这可以很容易地使用诸如Kue 之类的优先作业队列库来实现,默认情况下,它会将您的作业排队,并一次执行一个,(因此一次将卷号分配给一个表单) 这样您就不必担心并发问题。

在典型的实现中,一旦表单对象被成功持久化,您将创建一个用于分配卷号的作业并将其添加到队列中。

注意:由于在响应返回给客户端后,滚动编号分配将在后台异步完成,因此您需要实现一种机制(即使用 Web 套接字或轮询)以让客户知道何时分配了卷号并将其显示在 UI 上。

可能还有其他比我在这里描述的更容易实现的方法。但是我的头上,这是我能想到的。

您还应该查看来自 MongoDB 文档的文章 Creating and Auto-Incrementing Sequence Field

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-10
    • 2017-11-09
    • 1970-01-01
    • 2018-05-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多