pdo = $pdoProvider->get(); } /** * Execute a query. */ public function execute(string $sql, bool $rerunIfDeadlock = false): PDOStatement { if ($this->logAll) { $this->logger?->info("SQL: " . $sql); } if (!$rerunIfDeadlock) { return $this->executeSqlWithDeadlockHandling($sql, 1); } return $this->executeSqlWithDeadlockHandling($sql); } private function executeSqlWithDeadlockHandling(string $sql, ?int $counter = null): PDOStatement { $counter = $counter ?? self::MAX_ATTEMPT_COUNT; try { $sth = $this->pdo->query($sql); } catch (Exception $e) { $counter--; if ($counter === 0 || !$this->isExceptionIsDeadlock($e)) { /** @var PDOException $e */ throw $e; } return $this->executeSqlWithDeadlockHandling($sql, $counter); } if (!$sth) { throw new RuntimeException("Query execution failure."); } return $sth; } private function isExceptionIsDeadlock(Exception $e): bool { if (!$e instanceof PDOException) { return false; } return isset($e->errorInfo) && $e->errorInfo[0] == 40001 && $e->errorInfo[1] == 1213; } }