尝试在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会在脚本终止后自动释放锁吗?
答案 0 :(得分:0)
13.3.4。咨询锁
PostgreSQL提供了一种创建锁的方法 应用定义的含义。这些被称为咨询锁,因为 系统不强制使用它 - 由应用程序决定 正确使用它们。咨询锁可用于锁定 对于MVCC模型来说难以适应的策略。例如,a 常见的使用咨询锁是模仿悲观锁定 所谓的平面文件的典型策略"数据管理系统。 虽然存储在表中的标志可用于相同的目的, 咨询锁更快,避免表膨胀,并且是自动的 在会话结束时由服务器清理。
在PostgreSQL中获取咨询锁有两种方法:at 会话级别或事务级别。一旦获得会议级别, 在明确发布或会话之前一直保持咨询锁定 结束。与标准锁定请求不同,会话级别的建议锁定 请求不遵守事务语义:在a期间获取的锁 稍后回滚的事务仍将保持在 回滚,同样,即使呼叫,解锁也是有效的 交易失败了。可以通过其多次获取锁定 拥有过程;对于每个完成的锁定请求,必须有一个 实际释放锁之前的相应解锁请求。 另一方面,事务级锁定请求的行为更像 常规锁定请求:它们会在结束时自动释放 事务,并没有明确的解锁操作。这个 行为通常比会话级行为更方便 短期使用咨询锁。会话级和 对同一个咨询锁标识符的事务级锁请求 将以预期的方式阻止对方。如果会话已经存在 一个给定的咨询锁,它的额外请求将始终成功, 即使其他会议正在等待锁定;这种说法是对的 无论现有的锁定保持和新请求是否在 会话级别或事务级别。
http://www.postgresql.org/docs/9.1/static/explicit-locking.html