我正在运行一个高吞吐量的应用程序,在这个应用程序中,许多类似于拍卖的过程每秒都会发生,预算是基于拍卖中的出价来花费的。
然而,在出价和决定拍卖之间有一个轻微的延迟,所以开始发生的是:
两个类似的拍卖会在同一秒钟内由同一个出价最高的人赢得,但这两个拍卖会的总出价超过了用户的预算,因此当第二个拍卖会试图获得出价时,第一个拍卖会已经获得了出价,用户现在以负余额结束。
我知道这是一个复杂的问题,但我想知道你的意见。
有关我的应用程序的一些详细信息可能会让您深入了解哪些是正确的权衡:
出价通常比用户预算小得多,因此不允许用户花费5美元预算的最后几美分可能不是什么大问题,但出价没有限制,因此这实际上可能无助于降低风险(可能对低出价交易有效,但一旦用户出价,比如说,3美元的出价,预算仍然可以在一秒钟内从5美元涨到-7美元,只要以高于正常出价的价格赢得4次拍卖)。
不允许出价高于一定的预算比率也可以是一个可以接受的解决方案,但这可能会影响用户体验很大,出价/预算比率将是相当武断的。比例越低,预算就越安全,用户体验也就越差,但仍不能保证不会超出预算。
预定一段时间的出价也可以是一种选择,但由于每秒有10万用户多次出价,预定所有出价和释放资金的解决方案可能会变得相当复杂
简单地不支付第二笔交易也可能是一个(相当糟糕和不公平的)解决方案,但它可能会限制滥用这个bug的动机。
我知道这些细节都是解决问题的直接尝试,但都不够好,我很好奇你的意见是什么,是否有更好的办法来解决双倍开支问题。与比特币协议的解决方案不同,在我的例子中,“商品”的交换是实时完成的,一旦没有更多的资金可用,我就无法还原它(在我的例子中,商品是网站访问,所以它们是即时的,在交易结算之前无法存储,不能延迟)。
2条答案
按热度按时间lvjbypge1#
您可以使用分布式锁来解决双重消费/双重预订问题。您至少需要获得三个可以更新的锁
用户预算,即投标人账户余额
卖方账户余额
拍卖
您还可以创建出价分类账来验证用户的支出、卖家帐户余额和用户的钱包余额。您可以每小时或每10分钟运行一次cron作业,以验证任何错误,并通知支持/开发人员检查潜在的错误。
你的逻辑可能是这样的
每个执行器都可以使用自己的标识id作为锁值,以避免释放其他人的锁。
qcbq4gxm2#
这可能奏效:改变赢得拍卖的规则。
现在,我猜,一个用户赢得了一场拍卖,如果她是拍卖结束时出价最高的人。您可以更改规则,以便用户必须是高出价者,并且有足够的预算来支付出价。如果这两个标准都不满足,下一个最高的投标人有足够的预算获胜。
这很容易向用户解释。”要想赢,你需要足够的预算。如果你失去了拍卖,你可以增加预算。”
在实现方面,您可以使用数据库事务来处理“win”操作。在单个数据库事务中,借记中标买家的预算,贷记卖家的帐户。
您可以使用如下sql序列: