首页 > 解决方案 > 在并行 HTTP 请求中正确扣除信用余额的设计模式

问题描述

为简单起见,假设用户可以从我的网站购买预付积分。然后用户可以向我的 API 服务发出 HTTP 请求。每个 HTTP 请求将花费 1 个积分。我还在一个表中记录了请求(如分类帐)并计算新余额信用并更新另一个表中的值。

我的问题是当用户的余额信用为 1 并开始同时发出多个 HTTP 请求(并行)时,我的服务器中的授权策略将简单地接受他们的所有请求,因为他们在发出该请求时还剩下 1 个信用余额. 有没有我可以实施的设计模式或任何解决方案来避免这种竞争条件?

我考虑过一些解决方案,例如实现队列系统和数据库行锁定。但这一切似乎都令人费解,而且在这方面经验很少,我认为很多人都可能出错。

如果有可靠的设计模式或解决方案可以解决这个问题,我也准备好完全重写。

标签: databasedesign-patternsdatabase-designsoftware-designaccounting

解决方案


我认为有3种主要方法可以解决这个问题:

  1. 与多线程的强一致性:你必须有一个锁定机制。带有重试的乐观锁定或悲观锁定。由于这里期望并发,乐观锁定可能是一个糟糕的选择。悲观锁可能在应用程序级别或数据库级别。

  2. 收件箱模式(actor-model):按顺序从收件箱(队列)处理消息的单个处理线程。

  3. 最终一致性:检测违规行为并采取补偿措施。例如,您会检测透支并收取超出限额的罚款。

我可能会在这里选择 #1(悲观锁定),除非您拥有实现 #2 所需的所有基础设施,而无需自己实现收件箱等。请注意,您不会锁定 HTTP 请求的整个执行,只是需要什么要同步。


推荐阅读