首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何防止日历预订系统中的重叠预订

如何防止日历预订系统中的重叠预订
EN

Software Engineering用户
提问于 2019-01-28 18:07:27
回答 3查看 2.8K关注 0票数 7

作为练习,我正在尝试为多个会议室设计一个简单的日历预订系统。我有点担心一些要求,比如在给定的时间范围内找到可用的房间,查找房间预订情况。然而,我似乎有点停留在预订场景上,比如在特定的比赛情况下,两个用户试图在同一时间预订A房,他们选择的时间范围可能完全相同或重叠。例如,用户1试图从上午10点到下午12点预订A室,用户2试图从上午9点到上午11点预订A室。当查找可用时间时,这个房间出现给两个用户,表示在所要求的时间框架内可用。在这种情况下,由于它们是重叠的,我只能接受一个预订而另一个失败,为了简单起见,我不会给任何用户优先权,而只是先到先得。我如何有效地解决这部分问题?我想用几种方法来处理这个问题:

  1. 让预订在请求中传递,使用队列对预订进行后处理,每次我去排队时,在实际插入DB之前执行可用性检查,确认预订。在提议的场景中,只有一个预订可以首先进入队列,因此第二个预订将失败。然后,系统将转过来,并通知用户,他们的预订,要么失败,要么通过。(我意识到这与Outlook如何处理他们的会议室设置类似)。但是这是一个很短的时间,这迫使我在一个线程中处理队列,然后我可以维持顺序,如果我得到两个线程去排队,我返回到循环中,现在两个线程在执行重新检查条件时会看到相同的结果,因为我计划分发这个进程。
  2. 试着在时隙上加个锁。但这只有在我预先为房间设置时间时间(例如,固定在9-10,10-11,.)的情况下才能起作用,这辜负了我在任何时间范围内保持预订系统开放的目的。对此,在这样的系统中,与数据库对话时,读写是否可以接受?因为如果我要对记录设置一个乐观的锁,那么在写入DB之前,我需要读取行来比较版本吗?
  3. 我可以看到这项工作的另一种方式是让请求通过,然后让另一个过程重新检查预订日历,以检测重叠,并且只保留第一个有效的预订。但我觉得这是没有效率的,因为我必须这样做,每次预订,如果房间是受欢迎的,许多用户想预订它。要扭转局面需要很长时间。

如果你要设计这样一个系统,你会怎么做呢?不管怎样,我们可以实时确认预订吗?如果预订单位在白天,在假设的情况下,只有一个房间是用户想要预订的,那么在这样的情况下,酒店预订系统将如何工作?

EN

回答 3

Software Engineering用户

发布于 2019-01-29 12:18:30

队列看起来是解决这个问题的一个很好的解决方案。体面的队列实现确保一个去队列操作只看到一条消息,这样您所描述的条件就不会发生(您没有考虑编写自己的队列,是吗?)请不要这样做)。

票数 2
EN

Software Engineering用户

发布于 2023-01-30 16:51:21

当您在agoda、预订或任何航班/酒店搜索平台中搜索任何内容时,给出特定的时间范围,然后选择航班/酒店,然后进行结账--您已经在顶部看到了一个计时器。计时器有一个有限的时间,最常见的5或10分钟。你得在那个时段内买东西。

计时器确保了一些事情-

  1. 如果你看到在那个日期范围内有房间/航班,它们仍然可用,它会一直等着你,直到计时器到期。
  2. 如果你看到房间以一定的价格出售,它也会确保在这段时间内房价保持不变,即使酒店老板想在这段时间内为某间房间更换房间,也不会立即反映

为了实现这样的延迟释放机制(基本上是锁),大多数实现都使用快速查找临时存储,比如redis。您不应该像任何数据库一样在这里使用持久存储。

你应该拥有的是-

  1. 用户1选择了房间,然后开始结帐,您将立即在您的redis缓存中对该房间资源创建一个锁。如何决定您的密钥将有助于您如何有效地实现锁定。
  2. 用户2仍在搜索,如果时间框架重叠,则不应看到任何锁定的资源。
  3. 用户2在一个搜索页面中,他已经选择了房间,并准备进行结账。在加载结帐页面之前,您将再次检查您的redis,并否认它现在不可用(就像您在类似的站点中看到的那样)。

如果您有多个redis副本,由于复制滞后,您仍然可以进入一种情况,当两者仍然能够继续直到签出。但是,这也是计时器可能会来拯救的地方;您可以进行连续的轮询,以查看状态是否仍然有效。如果您的查找现在返回,您不能再预订,您显示了相关的经验(即有人已经预订或其他)!

您甚至可以通过执行套接字推送来实现更智能的解决方案。发送拒绝推送如果在您的背景检查中,您看到当前签出开始于X时间,但在X- 0.001时间已经有另一个正在进行的签出,它现在可以在您的红皮书中使用。

我希望这能给你一些关于如何实现它的想法。

票数 1
EN

Software Engineering用户

发布于 2019-01-28 20:31:22

一种方法是把一天分成15分钟的增量。然后只需按房间、日期和间隔ID创建主键。如果有人试图插入另一条记录,将发生主键错误。对于这种方法,一个人只需要一个表。您不需要事务,因为数据库是原子的,不允许重复主键。

如果您希望能够预订任何时间段,那么就需要一个事务,因为使用键是有问题的。事务将必须查看表中的记录,并查看会议的开始和结束是否与任何其他记录重叠。如果是这样,返回消息说不能预订和结束交易,如果没有预订房间和完成交易。当你寻找,没有其他人可以预订,所以他们必须等到你的交易结束后,他们才能开始他们的。这会导致阻塞。为了减轻..。

在这种情况下,您可能希望每个房间都是自己的表,以便当您的锁定和该房间有事务时,其他预订其他房间的用户不必等到您的预订完成。这使整个房间具有更大的可伸缩性,并且只有当两个用户同时预订房间时才会阻塞(不太可能,但可能)。

票数 0
EN
页面原文内容由Software Engineering提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://softwareengineering.stackexchange.com/questions/386233

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档