简体   繁体   English

PostgreSQL咨询锁不适用于Doctrine的DBAL

[英]PostgreSQL advisory locks are not working with Doctrine's DBAL

I'm experiencing a very strange behavior when trying to use advisory locks in Doctrine's DBAL. 尝试在Doctrine的DBAL中使用咨询锁时遇到一种非常奇怪的行为。

I have a Symfony 2 application in which I want to obtain an advisory lock for some entity. 我有一个Symfony 2应用程序,我想在其中获取某些实体的咨询锁。 I'm making the following query to obtain the lock: 我正在执行以下查询来获取锁:

SELECT pg_try_advisory_lock(83049, 5)

Via the following code in PHP: 通过PHP中的以下代码:

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

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

I've created the following script to test the concurrency: 我创建了以下脚本来测试并发性:

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

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

However, when I run it concurrently, it looks like every instance is successfully getting the lock. 但是,当我同时运行它时,似乎每个实例都成功获取了锁。 Also, after request is terminated, it looks like lock is automatically released, even when I've not called unlock() . 同样,在请求终止后,即使我没有调用unlock() ,锁也似乎自动释放。

Why it behaving that way? 为什么会这样呢?

Does doctrine use single connection for all requests? 原则是否对所有请求都使用单一连接?

Does doctrine releases the locks automatically after script is terminated? 脚本终止后,学说会自动释放锁吗?

13.3.4. 13.3.4。 Advisory Locks 咨询锁

PostgreSQL provides a means for creating locks that have application-defined meanings. PostgreSQL提供了一种创建具有应用程序定义含义的锁的方法。 These are called advisory locks, because the system does not enforce their use — it is up to the application to use them correctly. 这些被称为咨询锁,因为系统不会强制使用它们-取决于应用程序是否正确使用它们。 Advisory locks can be useful for locking strategies that are an awkward fit for the MVCC model. 咨询性锁定对于不适用于MVCC模型的锁定策略很有用。 For example, a common use of advisory locks is to emulate pessimistic locking strategies typical of so-called "flat file" data management systems. 例如,咨询锁的常用用法是模拟所谓的“平面文件”数据管理系统特有的悲观锁策略。 While a flag stored in a table could be used for the same purpose, advisory locks are faster, avoid table bloat, and are automatically cleaned up by the server at the end of the session. 虽然存储在表中的标志可以用于相同的目的,但咨询锁更快,可以避免表膨胀,并在会话结束时由服务器自动清除。

There are two ways to acquire an advisory lock in PostgreSQL: at session level or at transaction level. 在PostgreSQL中有两种获取咨询锁的方法:在会话级别或在事务级别。 Once acquired at session level, an advisory lock is held until explicitly released or the session ends. 一旦在会话级别获取,将保持咨询锁,直到明确释放或会话结束为止。 Unlike standard lock requests, session-level advisory lock requests do not honor transaction semantics: a lock acquired during a transaction that is later rolled back will still be held following the rollback, and likewise an unlock is effective even if the calling transaction fails later. 与标准锁请求不同,会话级咨询锁请求不遵循事务语义:在回滚后的事务中获取的锁在回滚后仍将保留,并且即使调用事务稍后失败,解锁同样有效。 A lock can be acquired multiple times by its owning process; 锁可以通过其拥有的过程多次获得; for each completed lock request there must be a corresponding unlock request before the lock is actually released. 对于每个完成的锁请求,在实际释放锁之前必须有一个相应的解锁请求。 Transaction-level lock requests, on the other hand, behave more like regular lock requests: they are automatically released at the end of the transaction, and there is no explicit unlock operation. 另一方面,事务级别的锁定请求的行为更类似于常规锁定请求:它们在事务结束时自动释放,并且没有显式的解锁操作。 This behavior is often more convenient than the session-level behavior for short-term usage of an advisory lock. 对于短期使用咨询锁,此行为通常比会话级行为更方便。 Session-level and transaction-level lock requests for the same advisory lock identifier will block each other in the expected way. 对同一咨询锁标识符的会话级和事务级锁请求将以预期的方式彼此阻塞。 If a session already holds a given advisory lock, additional requests by it will always succeed, even if other sessions are awaiting the lock; 如果一个会话已经拥有给定的咨询锁,则即使其他会话正在等待该锁,它的其他请求也将始终成功; this statement is true regardless of whether the existing lock hold and new request are at session level or transaction level. 无论现有的锁保持和新请求是在会话级别还是在事务级别,此语句都是正确的。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM