首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在同花顺时检查可用性

在同花顺时检查可用性
EN

Stack Overflow用户
提问于 2013-09-16 13:58:04
回答 2查看 405关注 0票数 1

假设我在一家流量很高的网上商店工作。出售的商品需求量很大,但也非常有限。我要确保它们不会被超卖。

目前我有这样的事情:

代码语言:javascript
运行
复制
$order->addProduct($product);
$em->persist($order);
if($productManager->isAvailable($product)){
    $em->flush();
}

然而,我认为,如果在很短的时间内收到两个订单,这仍然允许超卖一种产品。还有什么其他的可能性,以确保产品绝对不会被超卖?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-09-16 16:26:43

您需要在事务中使用悲观锁

假设您的Product实体有一个count字段,其中包含剩余的项目数。在用户购买项目后,您将减少该字段。

在这种情况下,您需要一个悲观的写锁。基本上,它会锁定行,使其不被试图获取悲观锁的其他进程读取和/或更新。这些进程一直处于锁定状态,直到锁定行的事务通过提交或回滚或超时结束为止。

因此,您启动一个事务,获取一个锁,检查是否还剩足够的项目,将它们添加到订单中,减少项目数并提交事务:

代码语言:javascript
运行
复制
$em->beginTransaction();

try {
    $em->lock($product, LockMode::PESSIMISTIC_WRITE);

    if ($product->getCount() < $numberOfItemsBeingPurchased) {
        throw new NotEnoughItemsLeftInStock;
    }

    $order->addItem($product, $numberOfItemsBeingPurchased);
    $product->decreaseCount($numberOfItemsBeingPurchased);

    $em->commit();
} catch (Exception $e) {
    $em->rollback();
    throw $e;
}

我建议在这里抛出一个例外,因为两个用户同时购买最后一个项目是一个例外的情况。当然,在运行此代码之前,您应该使用某种类型的项计数检查-验证约束或其他什么。因此,如果一个用户已经通过了该支票,但另一个用户在支票之后,在当前用户实际购买之前购买了最后一个项目,这是一种例外情况。

还要注意,您应该在单个HTTP请求期间启动和结束事务。我的意思是,不要在一个HTTP请求中锁定一行,等待用户完成购买,然后才释放锁。如果你想让用户能够把物品放在他们的车里一段时间--就像在现实世界的车里一样--使用其他方法,比如为用户保留一个产品一段时间,方法是仍然减少库存物品的数量,并在超时后将其释放。

票数 1
EN

Stack Overflow用户

发布于 2013-09-16 14:05:03

关于Doctrine2有一个完整的章节讨论并发性,这正是您所需要的。

您需要处理事务自定义查询,并在查询期间锁定您的表。这一切在这里都有解释:事务和并发

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18829884

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档