php - 避免重复预订/重复消费

标签 php mysql redis transactions bitcoin

我正在运行一个高吞吐量应用程序,其中每秒都会发生许多类似拍卖的流程,并且预算是根据拍卖中标出价花费的。

但是,从出价到决定拍卖之间存在轻微的延迟,所以开始发生的事情是这样的:

  • 同一个最高出价者在同一秒内赢得了两次类似的拍卖,但两次拍卖的总出价超出了用户的预算,因此当第二次拍卖试图获得出价时,第一次拍卖已经得到它,用户现在最终余额为负。

我确实知道这是一个复杂的问题,但我想知道您的意见。

有关我的应用程序的一些详细信息可能会提供有关正确权衡的见解:

  • 出价通常远小于用户预算,因此不允许用户花掉 5 美元预算的最后几美分可能不是一个大问题,但出价没有限制,因此事实上,这可能无助于降低风险(可能适用于低价交易,但一旦用户提出 3 美元的出价,预算仍然可以在一秒钟内从 5 美元变为 - 7 美元,通过获胜只有 4 次拍卖的出价高于正常出价)。

  • 不允许出价高于一定的预算比率也是一个可以接受的解决方案,但这可能会极大地影响用户体验,并且出价/预算比率将相当任意。比例越低,预算越安全,用户体验越差,但仍不能保证不超出预算。

  • 预订特定时间的出价也是一种选择,但由于每秒有 10 万用户出价多次,预订所有出价和释放资金的解决方案可能会变得相当复杂

  • 简单地不支付第二笔交易也可能是一个(相当蹩脚且不公平)的解决方案,但它可能会限制滥用此错误的动机。

我意识到这些细节都是解决问题的直接尝试,但没有一个足够好,我很好奇您的意见是什么,以及是否有更好的解决方案来解决双花问题。与比特币协议(protocol)的解决方案不同,在我的例子中,“商品”的交换是实时完成的,一旦没有更多可用资金,我就无法恢复它(在我的例子中,商品是网站访问,所以它们'是即时的,交易结算后才能存储,不能延迟)。

最佳答案

这可能有效:更改赢得拍卖的规则。

现在,我猜想,如果用户是拍卖结束时出价最高的人,她就赢得了拍卖。您可以更改规则,以便用户必须既是最高出价者,又具有足够的预算来支付出价。如果这两个条件都不满足,则具有足够预算的次高出价者获胜。

这很容易向用户解释。 “要获胜,您需要有足够的预算。如果您在拍卖中失败,您可以增加预算。”

在实现方面,您可以使用数据库事务来处理“win”操作。在单个数据库交易中,借记获胜买家的预算并贷记卖家的帐户。

您可以像这样使用 SQL 序列:

START TRANSACTION;
SELECT budget 
  FROM user 
 WHERE id = nnnn 
   AND budget >= bid
   FOR UPDATE;
/* if you got a result do this */
UPDATE user SET budget=budget-bid 
 WHERE id= nnnn;
UPDATE seller SET balance=balance+bid 
 WHERE ID = sssss;
UPDATE auction
   SET winner=nnnn, winning_bid=bid,
       closetime=NOW()
 WHERE auction = aaaa;
COMMIT;
/* if you got no result from the SELECT do this */
ROLLBACK;

关于php - 避免重复预订/重复消费,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65358310/

相关文章:

java - Redis中的notify-keyspace-events是什么

docker - 使用 Docker Compose 创建同一服务的多个容器

php - 将用户直接转发到 PayPal 上的信用卡处理页面

php - "Notice: Undefined variable"、 "Notice: Undefined index"、 "Warning: Undefined array key"和 "Notice: Undefined offset"使用 PHP

javascript - 将数据插入两个表,结果为 "Array to string conversion"

mysql - 为什么带有 'exists' 的 sql 运行速度比使用 MySQL 的 'in' 慢

php - 保存 html 并登录数据库

mysql - 在 MySQL 数据库上操作字符串

MySQL - 计算通用值是否介于

laravel - 缓存 Redis 'Exception',消息为 'Serialization of ' Closure' is not allowed'