【发布时间】:2020-12-17 00:17:20
【问题描述】:
我有一个实时应用程序,用户在其中同时点击一个按钮。这是一个拼车应用程序,所有用户的屏幕上都会显示一个乘车,然后两个用户基本上会同时按下“接受乘车”按钮。这会产生问题,因为它通过数据库保存调用将第一个用户保存到骑行中,但随后第二个用户过度保存了第一个用户。一旦一个用户接受了乘车,另一个用户应该不能接受乘车。它产生了很大的问题,因为第一个用户应该只是“接受乘车”,而对于第二个司机,它应该只是告诉他们“另一个司机正在接受乘车”。问题是我什至无法运行查询来检查骑行是否已经有司机,因为这一切都发生得如此之快。第一个用户将点击“接受乘车”,然后将他们保存到乘车中。第二个用户将点击“接受乘车”,它会检查乘车是否已经有司机。它还没有,因为第一次保存仍在完成。然后第二个用户在旅途中被超额保存。它只是在查询不能真正解决问题的同时发生。
对不起,如果这是一个令人困惑的解释。我从来没有处理过这个问题的实时性,所以我不知道从哪里开始。我想我需要建立一些队列或一些只让这种情况一次发生的东西。甚至谷歌的任何方向都会有所帮助。谢谢!我的后端是用 node.js 编写的,我在 Heroku 上使用 MongoDB。
【问题讨论】:
-
您需要在数据库中进行原子检查和设置操作,因此在一个原子数据库操作中,您可以验证它尚未被接受,如果没有,则接受它。这将只允许一个人接受它,任何其他人都会失败,因为它已经被接受并且 API 可以将其反馈给用户界面。这里的关键词是“原子”,如何实现它取决于特定的数据库。对于 MongoDB,请参阅Mongo any way to do atomic check and set。
-
这些解决方案使用 mongodb 的 findandmodify ,因此您可能会尝试查找具有此 id 的文档并且该文档也不被接受,如果找到,您将对其进行修改以被接受。然后,由于 findandmodify 是原子的,没有其他人可以进入您的 find 和 modify 之间,因此当他们的 findandmodify 轮到他们时,他们将找不到既是正确 id 又不被接受的文档,因为其他人之前接受了它他们进来了。
-
谢谢。 findAndModify 解决方案有效
-
好的,我把我的 cmets 变成了答案。