Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/292.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 条令(postgresql)悲观锁定-不';t抛出悲观锁异常_Php_Postgresql_Doctrine Orm_Locking_Pessimistic - Fatal编程技术网

Php 条令(postgresql)悲观锁定-不';t抛出悲观锁异常

Php 条令(postgresql)悲观锁定-不';t抛出悲观锁异常,php,postgresql,doctrine-orm,locking,pessimistic,Php,Postgresql,Doctrine Orm,Locking,Pessimistic,我尝试在PostgreSql中使用悲观锁。 默认配置的条令和PostgreSql(无任何更改) 这是一个代码示例(Symfony命令) $sleep-这是以秒为单位的时间 $manager = $this->getContainer()->get('mmi.manager.message'); $conn = $manager->em()->getConnection(); $manager->em()->getConnection()->beginT

我尝试在PostgreSql中使用悲观锁。 默认配置的条令和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秒。第二个命令运行时没有任何超时

预期结果

第二个命令抛出悲观锁异常

实际结果

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

问题


如果行现在已锁定,我应该如何使Doctrine抛出悲观锁异常?

Fo首先:PostgreSql平台的悲观写操作如何

悲观写-这是查询
SELECT。。。用于更新
。此查询锁定所选行和其他连接,它们请求相同的行,等待当前连接完成其工作

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

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

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

我当前的实现要求锁定行具有nowait行为。PostgreSql 9.5有这个特性-。但条令并没有实现这个特性

我们能做什么?

我们可以从类中重写原则postgresql平台

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

#app/config/config.yml
doctrine:
    dbal:
        connections:
            mmi:
                driver:   pdo_pgsql
                host:     ...
                ...
                platform_service: 'mmi.dbal.pgsql_platform'
就这些。现在我们可以不用等待就使用悲观锁