Closed
Description
Symfony version(s) affected
5.4
Description
If a call to $lock->acquire(true)
errors, DoctrineDbalPostgreSqlStore doesn't relase it's internal store lock and prevents further locks from being acquired by the same process.
There's another ticket that fixes the same issue in save
and saveRead
here: #44828
How to reproduce
use Doctrine\DBAL\DriverManager;
use Symfony\Component\Lock\LockFactory;
use Symfony\Component\Lock\Store\DoctrineDbalPostgreSqlStore;
$connection = DriverManager::getConnection(['url' => getenv('DATABASE_URL')]);
$lockFactory = new LockFactory(new DoctrineDbalPostgreSqlStore($connection));
// set a very low statement time out so the lock acquisition fails
// this could be any reason for failure like a disconnect and reconnect, etc
// because the connection intance doesn't change and `spl_object_hash` doesn't
// change the underlying internal store won't change
$connection->executeStatement('SET statement_timeout = 1');
$lock1 = $lockFactory->createLock('test');
try {
$locked = $lock1->acquire(true);
} catch (Exception $e) {
echo 'error acquring lock: ', get_class($e), PHP_EOL;
}
// no timeout anymore, connection is "fixed" or reconnected, etc
$connection->executeStatement('SET statement_timeout = 0');
$lock2 = $lockFactory->createLock('test');
// this should work, but throws
$lock2->acquire(true);
Possible Solution
Implement the same fix from #44828 in waitAnd*
methods.
Additional Context
No response