【发布时间】:2021-12-01 03:31:57
【问题描述】:
考虑一个网络应用程序,学生可以在其中预订房间。现在可能会出现多个学生预订同一个房间导致数据错误的情况。如何避免这种事情?
我的想法:
学生预订的房间将存储在数据库中。因此,如果我使用数据库提供的事务的功能,那应该足以处理它
我不确定在 web 应用程序中编写的事务代码,比如用 java 语言,是否需要放在同步块中?
【问题讨论】:
考虑一个网络应用程序,学生可以在其中预订房间。现在可能会出现多个学生预订同一个房间导致数据错误的情况。如何避免这种事情?
我的想法:
学生预订的房间将存储在数据库中。因此,如果我使用数据库提供的事务的功能,那应该足以处理它
我不确定在 web 应用程序中编写的事务代码,比如用 java 语言,是否需要放在同步块中?
【问题讨论】:
要明确地回答这个问题实际上是不可能的; “正确”的方式取决于您的实现、工具、语言和所需的用户体验。
但是,对于用户体验和实施,有一些通用模型。 我在您的特定场景中看到的最常见的模型是:
预分配,选择房间作为预订候选会导致 Web 应用“锁定”该房间一段时间,让用户有机会完成预订。如果人们经常选择房间然后没有完成预订,这很烦人,因为这意味着房间将经常无法预订(但永远不会被预订)。
事务锁定,您尝试预订房间并允许来自数据库的事务异常表明它已被预订。如果房间需求量很大并且人们倾向于同时预订,这很烦人;他们最终会到达过程的最后并被激怒。
如果您的系统将只有一个 Web 服务器,我可能会倾向于前一种方法,它的超时时间很短。在流程结束时进行具体的房间选择(因此选择房间和完成预订之间的时间尽可能短)。假设处于该状态的用户将完成他们的预订,并且不会花费很长时间,然后相应地设置超时。然后,使用全局线程安全池控制并发,并依靠您的语言的安全并发访问模型来控制争用场景中的胜者。
【讨论】:
为了处理数据库中的逻辑,您必须正确锁定实体,同时检查您的预订是否存在,然后写入数据库。如果你这样做了,你可以释放锁。
这样你会得到一致的数据,这样就没有办法了,多次预约。
这样做,您不需要业务逻辑来处理锁定。您只是收到一些返回值,然后您必须决定要做什么。要么告诉用户预订成功,要么必须选择新的预订。
当然,您也可以在业务逻辑中进行锁定。在这种情况下,您不必锁定数据库。正如您所提到的,您需要一个同步块。在此块中,您进行检查并写入数据库。
【讨论】: