use*_*634 7 mysql innodb locking atomic escrow
我有一个网站,用户可以购买门票,但门票数量通常是有限的,并迅速进行.我正在尝试实施一个托管系统,以便用户可以点击他们想要x个票数,此时我会将它们置于托管状态.这给了他们几分钟的时间来输入他们的信用卡信息并完成购买.
我有三个相关的表:事件,门票和托管.事件表中的一行描述了事件本身,包括可用的最大票数.
票证表包含以下内容:
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.";
}
Run Code Online (Sandbox Code Playgroud)
我的问题是,多个用户可能同时执行此代码.如果一个用户beginEscrow 在另一个用户已经读过已经托管的门票数量之后打电话,我可能会超出节目.
我正在为我的表使用InnoDB引擎,并且我已经阅读了如何使用锁定单行SELECT .... FOR UPDATE,但我没有更新单行.该beginEscrow函数只会在托管表中插入一个新行.我$tickets_in_escrow通过读取具有正确事件ID的所有行并在每个行中添加票数来计算.
也许我一切都错了?
我需要锁定整个桌子吗?
我不能成为第一个写票证托管系统的人.我试图找到一些关于这种事情的教程,然后用谷歌搜索出来.任何想法都会有所帮助.
谢谢!
你的设计非常接近,但不是很完美.
首先,您的活动表需要保留您的活动仍然可用的门票数量(除了您想要的任何其他内容).
其次,您的托管表需要有一个DATETIME列,指示托管何时到期.门票进入托管时,您需要设置该值.
第三,将门票存入托管的交易需要
第四,完成销售的动作需要删除托管行并插入售票行.这并不难.
第五,你需要一个托管清理操作.这需要查找已过期的所有托管行(过去有过期日期),并且对于每个托管行:
诀窍是以正确互锁的方式维护可用票证的数量,因此用户之间的竞争条件不会超出您的事件.
| 归档时间: |
|
| 查看次数: |
3526 次 |
| 最近记录: |