Skip to main content
Drupal API
User account menu
  • Log in

Breadcrumb

  1. Drupal Core 11.1.x
  2. PdoSessionHandler.php

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\Handler

Code

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));
    }
}

API Navigation

  • Drupal Core 11.1.x
  • Topics
  • Classes
  • Functions
  • Constants
  • Globals
  • Files
  • Namespaces
  • Deprecated
  • Services
RSS feed
Powered by Drupal