- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我尝试将悲观锁与 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/
我正在尝试 JPA 对数据库锁定的支持,以避免记录中的并发请求。在我的场景中,我需要使用悲观锁。我使用以下方法得到了这一点: EntityManager em; ... Map props = new
我尝试将悲观锁与 Doctrine ORM 一起用于 PostgreSql。具有默认配置的 Doctrine 和 PostgreSql(没有任何更改)。 这是代码示例(Symfony 命令)。 $sl
我是一名优秀的程序员,十分优秀!