处理与Web应用程序后端有关的竞争条件的策略?

时间:2014-10-03 08:32:02

标签: multithreading web-applications backend race-condition

我经常在采访中被问到有关电子票务或旅游网站等网络应用中的竞争条件的问题。

问题是这样的。

  

对于公共汽车或机票网站说,只剩下座位。不同计算机上的两个(或许多极端情况下)用户同时登录网站并看到剩下一个座位。他们都继续前进,选择那个座位并下订单。

现在有两个我们必须处理的请求。对于第一个请求,我们将预订票证,但是对于第二个请求,我们必须抛出错误并向最终用户显示错误消息,说明座位不可用。 假设数据库模式是这样的事情:

  

bus_id,seat_id,is_taken

所以对于第一个请求,我们为相应的bus_id,seat_id 1创建了is_taken。然后对于第二个请求,没有任何seat_id,is_taken = 0,所以我们不会预订票证。

但是,在我看来,我们已经制定了限制,一次只能处理一个请求;只有在第一次请求完成后才能处理第二个请求。

然而,这是不切实际的,因为我们可能有一个巨大的网站,其中包含大量流量和应用程序并行运行在多个服务器上。我们必须并行处理请求。

由于我在处理这类多线程Web应用程序中的竞争条件方面没有太多经验,所以我无法确定解决这个问题的正确方法。

解决这些问题的正确(即使是基本的)方法/设计模式是什么?

2 个答案:

答案 0 :(得分:2)

Web应用程序必然是多线程的。有两种方法可以解决这个问题。

  1. 申请级别(不是首选) 我不确定您使用哪种编程语言来构建应用程序。但是,用于构建网站的所有编程语言都将具有类似于" synchornize"这允许您防止两个线程同时访问相同的代码块。 这不是优选的,因为该解决方案不能水平扩展。当您决定通过再运行一个Web应用程序实例来增加容量时,此解决方案就会失败。

  2. 数据库级别 这是首选的解决方案。在更新之前,您将获取数据库中记录的锁定。 SQL提供了一个选择更新记录的选项。

    SELECT * FROM BUS_SEATS WHERE BUS_ID = 1 FOR UPDATE;

    以上sql是获取锁定的一种方法。所有数据库都提供这种功能。使用此功能,您可以锁定所需的行并执行更新并确保数据库的一致性。

答案 1 :(得分:1)

在某些时候,必须有某种同步。 由于您使用的数据库通常是瓶颈,因此您可以让它处理竞争条件。

您所要做的就是以原子方式更新行。申请仍然可以并行处理。

SQL的伪代码:

DECLARE @success = false;

UPDATE bus_seats
SET is_taken = 1, success = true
WHERE seat_id = @seat_id AND is_taken=0

return @success;