我有一个网站,用户可以购买门票,但门票数量通常是有限的,并迅速前往。我正在尝试实现一个托管系统,这样用户就可以点击他们想要的x号票,此时我会将它们置于托管状态。这给了他们几分钟的时间输入信用卡信息并完成购买。
我有三个相关的表格:活动,门票和托管。events表中的一行描述事件本身,包括可用的最大票数。
入场券表可容纳下列物品:
user_id:买票的用户
number_of_tickets:他们买了多少张票
event_id:相关事件
托管表包含以下内容:
user_id:购票过程中的用户
number_of_tickets:他们想要多少张票?
event_id:相关事件
目前,我执行三次MySQL查询,一次查询最大票,一次查询售票数量,以及一次查询已经代管的票数。然后我计算:
$remaining_tickets = $max_tickets - $tickets_sold - $tickets_in_escrow;
if ($remaining_tickets >= $tickets_desired)
{
beginEscrow($user_id, $event_id, $tickets_desired);
}
else
{
echo "Error: not enough ticket remain.";
}我的问题是,多个用户同时执行此代码是可能的。如果一个用户在另一个用户已经阅读了代管票的数量之后打电话给beginEscrow,那么我可能会超卖这个节目。
我正在为我的表使用InnoDB引擎,我已经阅读了如何使用SELECT .... FOR UPDATE锁定单个行,但我没有更新一行。beginEscrow函数将只在托管表中插入一个新行。我通过读取具有正确事件id的所有行并将每个行中的票数相加来计算$tickets_in_escrow。
也许我搞错了?
我需要锁整张桌子吗?
我不能是第一个写罚单代管系统的人。我在googled上搜索了一些关于这类东西的教程,但是被删除了。任何想法都会有帮助。
谢谢!
发布于 2012-07-01 00:07:22
你离你的设计很近,但不太接近。
首先,您的活动表需要保存您的活动仍然可用的票的数量(除了您想要的其他任何东西)。
其次,您的代管表需要有一个日期时间列,指示托管到期的时间。您需要在入场券进入托管时设置该值。
第三,代管票的交易需要
第四,完成销售的操作需要删除托管行并插入销售票行。这并不难。
第五,你需要一个托管清理操作。这需要查找已过期(过去有过期日期)的所有代管行,并为每个行查找:
诀窍是以一种正确的互锁方式保持可用票的数量,这样用户之间的竞争条件就不会过度推销您的事件。
https://stackoverflow.com/questions/11278494
复制相似问题