我正在创建一个预订系统,允许用户进行一整天的预订。当用户最初想预订时,他们会选择当天(S),然后用10分钟来填写剩余的信息。
我是如何做到这一点的:有一个booked字段和一个lockedUntil字段,这样只要有booked预订或将来有lockedUntil的预订,其他的预订就不能在同一天进行。
现在,由于我使用mongodb,为了执行唯一性,在插入之前,我一直在检查任何相互冲突的保留。我最近才意识到,如果有两个预约没有冲突地回来,然后两个人都被插入,我才意识到比赛的条件。显然这是个很大的不-不。
我的问题归结为:考虑到可维护性,执行日期唯一性的最佳方法是什么?
我试图实现的是日期上的唯一索引,以便在存在竞争条件的情况下,至少在数据库级别上会阻止它。这似乎很好,直到我意识到我无法处理那些还不是booked但只是被lockedUntil锁定的预订。现在,我可以设置一个TTL索引来删除这些保留,但这将导致长达60秒的窗口,其中唯一的约束将失败。此外,这将使我们无法看到未完成的预订,这可能是有价值的。
也许有更好的方法来实现我想要的。我曾想过使用事务,但我担心的是,如果它被控制在应用程序级别,一个预订可能会溜走,最终导致数据库中的双重预订。
还有什么办法我可能不想呢?是否有更好的方法来控制预订的锁定?
发布于 2020-02-17 19:08:57
如果您在预订日期上设置了一个唯一的索引,那么就应该这样做,并按照下面的内容进行如下操作。一旦用户开始编辑记录并输入预订日期,就会将临时保留记录插入到MongoDB中,以防止其他人开始保留同一日期。如果他们试图在“保留日期”字段中输入日期,并且该日期已被保留,则不允许将该日期保留在“保留日期”字段中。一旦他们成功地输入了日期,如果他们更改了日期,您必须删除占位符,并将新的占位符重新插入到您的MongoDB中。如果10分钟的预订期限到期,而他们还没有完成预订,则保留人(记录)将从MongoDB中删除。如果他们完成了保留,保留人的记录就会“完成”--变成一个永久的保留。
发布于 2020-02-17 22:09:16
您可能需要一个附带的表,其中列出了所有的天数(搜索如何创建一个日期维度关于如何创建日期)
那你就可以
create table reservations(dayid int, user varchar(100), lockeduntil datetime)
update reservations
set lockeduntil = SYSDATE(), user = "Miller"
where dateid = 01012021 and lockeduntil IS NULL根据酸的原子性(sp?)保证,这将运行或不运行。(争用失败将返回成功,但不更新任何行)
https://softwareengineering.stackexchange.com/questions/403741
复制相似问题