You are here

private function PdoSessionHandler::doAdvisoryLock in Zircon Profile 8.0

Same name and namespace in other branches
  1. 8 vendor/symfony/http-foundation/Session/Storage/Handler/PdoSessionHandler.php \Symfony\Component\HttpFoundation\Session\Storage\Handler\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

Parameters

string $sessionId Session ID:

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 576

Class

PdoSessionHandler
Session handler using a PDO connection to read and write data.

Namespace

Symfony\Component\HttpFoundation\Session\Storage\Handler

Code

private function doAdvisoryLock($sessionId) {
  switch ($this->driver) {
    case 'mysql':

      // 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', $sessionId, \PDO::PARAM_STR);
      $stmt
        ->execute();
      $releaseStmt = $this->pdo
        ->prepare('DO RELEASE_LOCK(:key)');
      $releaseStmt
        ->bindValue(':key', $sessionId, \PDO::PARAM_STR);
      return $releaseStmt;
    case 'pgsql':

      // Obtaining an exclusive session level advisory lock requires an integer key.
      // So we convert the HEX representation of the session id to an integer.
      // Since integers are signed, we have to skip one hex char to fit in the range.
      if (4 === PHP_INT_SIZE) {
        $sessionInt1 = hexdec(substr($sessionId, 0, 7));
        $sessionInt2 = hexdec(substr($sessionId, 7, 7));
        $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 = hexdec(substr($sessionId, 0, 15));
        $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));
  }
}