如何处理竞争条件

How to deal with a race condition

我对网络开发还很陌生。从我读到的竞争条件来看,我认为节点或 JS 是不可能的,因为它是单线程的,但我看到那是..我猜错了。有人可以通过这个小例子解释它是如何工作的。

如果有一个银行帐户中有 1000 美元,并且两个人在同一时间向该帐户收费,同时访问服务器。第一个人收费 600 美元,第二个人收费 200 美元。

第一笔费用为 1000 美元 - 600 美元,余额为 400 美元。 但由于第二次收费是在同一时间发生的,因此它会产生 1000 美元 - 200 美元,从而使余额保持在 800 美元。显然余额现在应该是 200 美元。

根据我的理解,这会导致竞争条件,不是吗?你会如何设置它来避免这个问题?我不需要确切的代码,只需要有人向我解释这个,或者伪代码。

提前致谢。

编辑:我将针对最初导致竞争条件的代码设置方式对其进行编辑。

就像下面的post说的。代码将被设置为当账户被击中时它会减去金额并给出新的余额。显然这会导致竞争条件。

如果没有看到正在使用的确切代码,就无法具体回答您的示例,因为有安全的方式来编写该代码,也有不安全的方式来编写它。

node.js 是单线程的,但是只要一个请求发出异步调用,其他请求就可以 运行 同时执行该异步请求。因此,您可以同时处理多个请求。这是否会导致 "race condition" 完全取决于您编写代码的方式,在特定情况下,还取决于您访问数据库的方式。

如果你这样写代码(伪代码):

 get total from database
 subtract from total
 write new total to database

并且,对数据库的调用是异步的(它们很可能是),那么您肯定会遇到竞争条件,因为在您获取总数和写入总数之间,其他请求可能会尝试访问相同的总值并尝试修改它,并且一个请求将没有最新的总值,或者两个请求将相互影响对方的结果(一个覆盖另一个)。

另一方面,如果您有一个数据库可以对数据库中的总值进行原子修改,如下所示:

subtract x from total in database

然后,您将免受该特定竞争条件的影响。


因为 node.js 是单线程的,所以在 node.js 中编写安全代码并不像在多线程 Web 服务器中那样复杂。这是因为同时执行的路径只有Javascript一条。因此,在您进行某种异步 I/O 调用之前,不会有其他请求同时 运行ning。这使得在您的 node.js 应用程序中访问共享变量比在真正的多线程 Web 服务器环境中要简单得多,在真正的多线程 Web 服务器环境中,对共享变量的任何访问都必须由互斥锁(或类似的东西)保护。但是,一旦你进行异步调用,你必须意识到在那个时间点,其他请求可以 运行.