PostgreSQL顾问锁不能与Doctrine的DBAL一起使用

时间:2015-03-30 20:17:51

标签: postgresql symfony doctrine dbal

尝试在Doctrine的DBAL中使用advisory locks时,我遇到了一种非常奇怪的行为。

我有一个Symfony 2应用程序,我想在其中获取某个实体的建议锁。我正在进行以下查询以获取锁定:

SELECT pg_try_advisory_lock(83049, 5)

通过PHP中的以下代码:

/** @var Doctrine\DBAL\Connection  */
protected $connection;

public function lock()
{
    return $this->connection->fetchColumn(
        "SELECT pg_try_advisory_lock({$this->getTableOid()}, {$this->entity->getLockingId()})"
    );
}

我已经创建了以下脚本来测试并发性:

// Obtaining the lock.
$locker->lock();

// Doing something for ten seconds.
sleep(10); 

但是,当我同时运行它时,看起来每个实例都成功获得锁定。此外,在请求终止后,即使我没有调用unlock(),看起来锁也会自动释放。

为什么这样做?

doctrine是否对所有请求使用单一连接?

doctrine会在脚本终止后自动释放锁吗?

1 个答案:

答案 0 :(得分:0)

  

13.3.4。咨询锁

     

PostgreSQL提供了一种创建锁的方法   应用定义的含义。这些被称为咨询锁,因为   系统不强制使用它 - 由应用程序决定   正确使用它们。咨询锁可用于锁定   对于MVCC模型来说难以适应的策略。例如,a   常见的使用咨询锁是模仿悲观锁定   所谓的平面文件的典型策略"数据管理系统。   虽然存储在表中的标志可用于相同的目的,   咨询锁更快,避免表膨胀,并且是自动的   在会话结束时由服务器清理。

     

在PostgreSQL中获取咨询锁有两种方法:at   会话级别或事务级别。一旦获得会议级别,   在明确发布或会话之前一直保持咨询锁定   结束。与标准锁定请求不同,会话级别的建议锁定   请求不遵守事务语义:在a期间获取的锁   稍后回滚的事务仍将保持在   回滚,同样,即使呼叫,解锁也是有效的   交易失败了。可以通过其多次获取锁定   拥有过程;对于每个完成的锁定请求,必须有一个   实际释放锁之前的相应解锁请求。   另一方面,事务级锁定请求的行为更像   常规锁定请求:它们会在结束时自动释放   事务,并没有明确的解锁操作。这个   行为通常比会话级行为更方便   短期使用咨询锁。会话级和   对同一个咨询锁标识符的事务级锁请求   将以预期的方式阻止对方。如果会话已经存在   一个给定的咨询锁,它的额外请求将始终成功,   即使其他会议正在等待锁定;这种说法是对的   无论现有的锁定保持和新请求是否在   会话级别或事务级别。

http://www.postgresql.org/docs/9.1/static/explicit-locking.html