function PdoSessionHandler::doAdvisoryLock
Executes an application-level lock on the database.
@todo implement missing advisory locks
- for oci using DBMS_LOCK.REQUEST
- for sqlsrv using sp_getapplock with LockOwner = Session
Return value
\PDOStatement The statement that needs to be executed later to release the lock
Throws
\DomainException When an unsupported PDO driver is used
1 call to PdoSessionHandler::doAdvisoryLock()
- PdoSessionHandler::doRead in vendor/
symfony/ http-foundation/ Session/ Storage/ Handler/ PdoSessionHandler.php - Reads the session data in respect to the different locking strategies.
File
-
vendor/
symfony/ http-foundation/ Session/ Storage/ Handler/ PdoSessionHandler.php, line 688
Class
- PdoSessionHandler
- Session handler using a PDO connection to read and write data.
Namespace
Symfony\Component\HttpFoundation\Session\Storage\HandlerCode
private function doAdvisoryLock(string $sessionId) : \PDOStatement {
switch ($this->driver) {
case 'mysql':
// MySQL 5.7.5 and later enforces a maximum length on lock names of 64 characters. Previously, no limit was enforced.
$lockId = substr($sessionId, 0, 64);
// should we handle the return value? 0 on timeout, null on error
// we use a timeout of 50 seconds which is also the default for innodb_lock_wait_timeout
$stmt = $this->pdo
->prepare('SELECT GET_LOCK(:key, 50)');
$stmt->bindValue(':key', $lockId, \PDO::PARAM_STR);
$stmt->execute();
$releaseStmt = $this->pdo
->prepare('DO RELEASE_LOCK(:key)');
$releaseStmt->bindValue(':key', $lockId, \PDO::PARAM_STR);
return $releaseStmt;
case 'pgsql':
// Obtaining an exclusive session level advisory lock requires an integer key.
// When session.sid_bits_per_character > 4, the session id can contain non-hex-characters.
// So we cannot just use hexdec().
if (4 === \PHP_INT_SIZE) {
$sessionInt1 = $this->convertStringToInt($sessionId);
$sessionInt2 = $this->convertStringToInt(substr($sessionId, 4, 4));
$stmt = $this->pdo
->prepare('SELECT pg_advisory_lock(:key1, :key2)');
$stmt->bindValue(':key1', $sessionInt1, \PDO::PARAM_INT);
$stmt->bindValue(':key2', $sessionInt2, \PDO::PARAM_INT);
$stmt->execute();
$releaseStmt = $this->pdo
->prepare('SELECT pg_advisory_unlock(:key1, :key2)');
$releaseStmt->bindValue(':key1', $sessionInt1, \PDO::PARAM_INT);
$releaseStmt->bindValue(':key2', $sessionInt2, \PDO::PARAM_INT);
}
else {
$sessionBigInt = $this->convertStringToInt($sessionId);
$stmt = $this->pdo
->prepare('SELECT pg_advisory_lock(:key)');
$stmt->bindValue(':key', $sessionBigInt, \PDO::PARAM_INT);
$stmt->execute();
$releaseStmt = $this->pdo
->prepare('SELECT pg_advisory_unlock(:key)');
$releaseStmt->bindValue(':key', $sessionBigInt, \PDO::PARAM_INT);
}
return $releaseStmt;
case 'sqlite':
throw new \DomainException('SQLite does not support advisory locks.');
default:
throw new \DomainException(\sprintf('Advisory locks are currently not implemented for PDO driver "%s".', $this->driver));
}
}