在数据库中释放库存的最佳实践

Posted

技术标签:

【中文标题】在数据库中释放库存的最佳实践【英文标题】:Best practice for releasing inventory in a database 【发布时间】:2011-07-04 12:09:45 【问题描述】:

我正在构建一个售票应用程序,用于跟踪门票库存,并在特定门票售罄时停用它们。

我想知道在中途放弃订单时将库存放回商店的最佳做法是什么。

当前流程:

用户将items 添加到orderline_items,并且order 被标记为成功支付完成 items 有一个 quantity_available,它是根据他们的 line_items 更新的 我定期扫描orders,超过 20 分钟没有任何操作,删除这些订单的line_items 并更新quantity_available

感觉好像我错过了一些东西。一方面,我失去了详细查看放弃订单的能力(我仍然有任何付款/拒绝等......但没有订单项)。如果用户在 21 分钟后尝试恢复旧订单,他们将不得不重新开始。

相反,它会占用 20 分钟的库存,这可能会在节目快售罄时失去我们的销售。

任何见解将不胜感激。谢谢。

【问题讨论】:

作为后续:我考虑在运行时计算line_items 以获得当前可用的库存as discussed here。对我来说,似乎需要对每笔交易执行该查询会很慢,并且缓存数量会更好。不过,我很可能是错的。 很难避免这种情况,但是我会存储每个预订/购买,当有人注册时,你会检查 count(r+p) 与 quantity_available (永远不应该调整)。如果您不这样做,您可能会遇到某些脚本/流程调整了数字但您看不到原因的情况 - 这可能导致过度/不足销售。仅供参考,我运行了几个这样的软件系统,并没有遇到“如果有人想要它但其他人保留它并且不使用它怎么办”的情况 - 但是(虽然我也担心它) 【参考方案1】:

如果我理解正确,听起来您应该将不同的步骤封装到一个回滚或暂停的单个事务中,如果没有及时完成 - 即您提到的 20 分钟。这样您就可以锁定和解锁 line_items 记录,而无需来回添加它们。

听起来您还需要考虑如何定义“订单”。您可能需要引入更多步骤。处理订单的过程是“预订”,只有在付款时才会确认。这样,您可以将库存释放到“保留”(过度保留是可以的)并且第一个付款的人得到订单。其他人失败了——他们应该更快!

【讨论】:

我很犹豫让人们最终在结帐页面上发现他们不够快。这可能是唯一的方法,但我知道,作为消费者,如果我开始下订单、去取信用卡然后回来发现我错过了,我会非常生气。 @AlexDunae,我分两步解决了这个问题。首先放一个打勾的时钟,告诉他们还有多少时间(以分钟和秒为单位)来完成订单,无论他们是否处于最后阶段甚至提供 CC 信息。其次,当订单正在进行时(正在付款),等待网关响应。如果打勾计数器用完并且如果付款被拒绝 - 那么客户会收到错误消息通知并且购物车也被清空。这样它工作正常!并在将付款信息发送到网关时维护库存,我只需将其标记为待付款 @AlexDunae,我在保留条件中计算付款待处理状态。如果付款被拒绝,则状态将变为待处理或拒绝或在滴答计数器用完时过期!【参考方案2】:

我想知道您为什么要根据未处理的订单来占用库存?我正在考虑像 Newegg 和 Amazon 这样的流行网站的工作方式。我可以创建一个购物车,它会无限期地存在。但它对我的库存没有任何作用,它只是数据库中的一条记录。使用 Newegg,我可以在几个月后回到该网站,而我废弃的购物车仍然在那里(过去这对我来说非常方便)。

您只能在用户完成订单时修改库存。这还可以让您生成关于废弃购物车的报告,因为您只需使用最后修改日期和订单完成来确定哪些购物车被废弃。

【讨论】:

例如,当只剩下一张票并且该票的两个订单都在进行中时会发生什么。从理论上讲,他们可以同时付款,但其中一个会倒霉。 您必须为此编写代码。如果您使用数据库交易,您始终可以在最后一步检查是否有任何其他订单耗尽了库存。如果是,则回滚。 当您查看路由器时,您选择哪一个并不重要。如果您在谈论预留座位,那非常重要。如果不是我选择的确切座位,我可能不想进行交易。 我注意到您在上面的后续跟进附加到了原始问题。我不会担心检查库存的性能。如果您为表编制索引,一个简单的检查库存查询应该只需要几毫秒。拥有良好的客户服务比为性能而编写代码要好。如果性能有问题,请升级硬件(或查看优化数据库/代码)。 :) 哦...我想我没有很好地阅读原始问题,也没有注意到我们在这里谈论的是活动门票。我完全同意,在这种情况下,您希望让用户在完成之前预订门票是有道理的。无视我的cmets。 :)【参考方案3】:

如何引入不同的标签:保留或其他东西。在处理订单时,您可以标记保留的票证,这会减少总库存计数。但是您现在确切地知道有多少票处于不确定状态。

在您长达 20 分钟的订单期间,如果现有商品数量非常少或为空,您可以向用户发送更新。 "订单已停滞 5 分钟。门票销售进展迅速,请尽快完成订单,以确保您的门票仍然可用。"

您还可以告诉潜在买家有 x 数量的预订门票可能可用,因此他们应该回来查看或其他什么。如果预订的票重新进入系统,也许他们可以注册接收电子邮件。

【讨论】:

我喜欢使用警告来增加紧迫感的想法。这肯定会增加一点前端复杂性,但它可能是值得的。 我最终做了这样的事情——我在line_items 中添加了一个名为affects_inventory 的列,即true 用于完成订单和挂单,false 用于放弃订单。 是的,前端变得更加复杂,可能还有 AJAXy,但作为消费者,我很欣赏这类消息。它可能会降低您的放弃率。

以上是关于在数据库中释放库存的最佳实践的主要内容,如果未能解决你的问题,请参考以下文章

技术干货|缓存一致性最佳实践

技术干货|缓存一致性最佳实践

在Cassandra 3.0多节点集群中回收磁盘空间的最佳实践

节点 js 应用程序中 db 连接池处理的最佳实践?

Go:分布式锁实现原理与最佳实践

微服务引擎的线上流量治理最佳实践