Php 条令(postgresql)悲观锁定-不';t抛出悲观锁异常
我尝试在PostgreSql中使用悲观锁。 默认配置的条令和PostgreSql(无任何更改) 这是一个代码示例(Symfony命令)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
$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'
就这些。现在我们可以不用等待就使用悲观锁