gpt4 book ai didi

php - Doctrine (postgresql) Pessimistic Locking - 不会抛出 PessimisticLockException

转载 作者:行者123 更新时间:2023-11-29 13:21:38 30 4
gpt4 key购买 nike

我尝试将悲观锁与 Doctrine ORM 一起用于 PostgreSql。具有默认配置的 Doctrine 和 PostgreSql(没有任何更改)。

这是代码示例(Symfony 命令)。

$sleep - 这是以秒为单位的时间

$manager = $this->getContainer()->get('mmi.manager.message');
$conn = $manager->em()->getConnection();

$manager->em()->getConnection()->beginTransaction();
try {
$entity = $manager->repo()->find('cd7eb9e9', LockMode::PESSIMISTIC_WRITE);

$entity->setState(EntityActionInterface::STATE_IN_PROGRESS);
$manager->em()->persist($entity);
$manager->em()->flush();

$ts = (new \DateTime())->getTimestamp();
$output->writeln("TS: {$ts}");

if ($sleep) {
$output->writeln("Sleep: {$sleep}");
sleep($sleep);
}

$entity->setMessage([$ts]);
$manager->em()->persist($entity);
$manager->em()->flush();

$conn->commit();
} catch (PessimisticLockException $ex) {
var_dump(get_class($ex));

$conn->rollBack();
throw $ex;
} catch (\Exception $ex) {
var_dump(get_class($ex));

$conn->rollBack();
throw $ex;
}

如何测试

运行两个命令。第一个命令运行超时 20 秒。第二个命令在没有任何超时的情况下运行。

预期结果

第二个命令抛出 PessimisticLockException

实际结果

第二个命令等待第一个事务提交,然后更新行。

问题

如果行现在被锁定,我应该怎么做才能让 Doctrine 抛出 PessimisticLockException

最佳答案

首先PESSIMISTIC_WRITE PostgreSql 平台的工作原理

PESSIMISTIC_WRITE - 这是查询 SELECT ... FOR UPDATE。此查询锁定选定的行和请求同一行的其他连接,等待当前连接完成它的工作。

在我的例子中,我启动了两个进程,第二个等待完成第一个。这是正确的行为。

我的错误:我正在探索 Doctrine 源代码并找到 PessimisticLockException 类。所以,我决定 Doctrine 在使用悲观锁时抛出这个异常。但是这个类没有在 Doctrine 中的任何地方使用。

那么,我是如何解决这个问题的。

我当前的实现需要锁定行的 nowait 行为。并且 PostgreSql 9.5 具有此功能 - SKIP LOCKED .但是 Doctrine 没有这个特性的实现。

我们能做什么?

我们可以覆盖 doctrine postgresql platfrom 类。

use Doctrine\DBAL\Platforms\PostgreSqlPlatform;

class PgSqlPlatform extends PostgreSqlPlatform
{
/**
* Returns the FOR UPDATE expression.
*
* @return string
*/
public function getForUpdateSQL()
{
return 'FOR UPDATE SKIP LOCKED';
}
}

定义为服务

#app/config/services.yml
services:
mmi.dbal.pgsql_platform:
class: {Namespace}\PgSqlPlatform

并设置tot doctrine config

#app/config/config.yml
doctrine:
dbal:
connections:
mmi:
driver: pdo_pgsql
host: ...
...
platform_service: 'mmi.dbal.pgsql_platform'

就是这样。现在我们可以不用等待就可以使用悲观锁了。

关于php - Doctrine (postgresql) Pessimistic Locking - 不会抛出 PessimisticLockException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40586294/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com