php doctrine concurrency pessimistic_write不能阻止额外的请求获取旧数据

sigwle7e  于 2023-06-28  发布在  PHP
关注(0)|答案(1)|浏览(91)

php:8.1教义:2.9.2
我在实现教义中的并发性时遇到了问题。我已经看过文档和一些问题,我不知道我的问题是什么。
我的应用程序正在追踪库存。多个请求可能会同时更新库存。我让他睡了一觉来测试。第二个请求等待第一个请求完成,因此锁看起来部分工作。但是,第二个请求使用起始库存,而不是第一个请求的调整库存。

  • 库存:50
  • 第一个请求:50 + 5 = 55
  • 第二个请求:50 + 5 = 55(应为55 + 5 = 60)

下面是持久化代码:

$this->em->beginTransaction();
    try{
        $inventoryID = $stockAdjustment->getInventory()->getId();
        $this->detach($stockAdjustment->getInventory());
        $inventory = $this->inventoryRepo->find($inventoryID, LockMode::PESSIMISTIC_WRITE);
        $this->refresh($inventory);
        sleep(15);
        $stockAdjustment->setInventory($inventory);
        $stockAdjustment->setPreAdjustmentStock($inventory->getStock());
        $inventory->modifyStock($stockAdjustment->getQuantity());

        $this->em->persist($inventory);
        $this->em->persist($stockAdjustment);
        $this->em->flush();
        $this->em->commit();
    }
    catch (\Throwable $e){
        $this->em->rollback();
        throw $e;
    }

在此发生之前,在水合调整时找到库存。我在分离和刷新行中留下了这两行,以表明我已经尝试过了。通常,InventoryMap到Inventory Adjustment并保持级联。在本例中,我删除了级联持久化,并直接保存库存。

mgdq6dx1

mgdq6dx11#

这是一个愚蠢的错误,我在发布后才意识到。根据库存的类型,库存可以是几种不同的类型,因此库存实际上并不存储在Inventory对象上。我有另一个类InventoryStock,并把锁上,解决了这个问题。InventoryStock有几个子类的鉴别器Map,但是锁定InventoryStock是有效的。

相关问题