我有一个产品可供抢购。第一个 claim 是最先得到的,但付款过程可能需要几秒钟才能完成,并且可能会失败。我不知道如何解决这个问题。
我正在使用此代码进行测试,并且我依次发送两个请求。等待 5 秒后,第一个成功完成。第二个我希望它等待第一个完成,然后看到它已经被声明,而是引发一个 Doctrine 锁定异常。
$em = $this->getDoctrine()->getManager();
//here I would expect it to wait until the lock is released.
$product = $em->getRepository(Product::class)->find(1);
if($product->getStatus() == Product::STATUS_PENDING){
$em->beginTransaction();
$em->lock($product, LockMode::PESSIMISTIC_READ);
try {
sleep(5);
if($paymentService->handlePayment($product)){
$product->setStatus(Product::STATUS_CLAIMED);
$em->persist($product);
$em->flush();
$em->commit();
}else{
$em->commit(); //to release the lock
//throw payment error
}
} catch (\Exception $e) {
$em->rollback();
throw $e;
}
die("success");
}else{
die("already sold");
}
最好的方法是什么?谢谢!
最佳答案
我在这里找到了答案: https://stackoverflow.com/a/17721736
$em = $this->getDoctrine()->getManager();
$em->beginTransaction();
$product = $em->find(Product::class,1,LockMode::PESSIMISTIC_WRITE);
if($product->getStatus() == Product::STATUS_PENDING){
$product->setStatus(Product::STATUS_CLAIMED);
$product->setName($val);
sleep(10);
$em->persist($product);
echo "done";
}else{
echo "already sold";
}
$em->flush();
$em->commit();
关于mysql - Symfony Doctrine (mysql)锁逻辑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58896336/