diff --git a/src/RetryConnection.php b/src/RetryConnection.php new file mode 100644 index 0000000..912acbb --- /dev/null +++ b/src/RetryConnection.php @@ -0,0 +1,108 @@ +retries = $numberRetries; + } + + /** + * Get the configured number of retries + * + * @return int + */ + public function getRetries(): int + { + return $this->retries; + } + + /** + * Set number of retries to be used + * + * @param int $retries + * + * @return $this + */ + public function setRetries(int $retries): self + { + $this->retries = $retries; + + return $this; + } + + public function prepexec($stmt, $values = null) + { + $retryHandler = function (int $retries = 0) use (&$retryHandler, $stmt, $values): PDOStatement { + try { + return parent::prepexec($stmt, $values); + } catch (Exception $err) { + if ($retries < $this->getRetries() && static::isRetryable($err)) { + $this->disconnect(); + + return $retryHandler(++$retries); + } + + throw $err; + } + }; + + return $retryHandler(); + } + + /** + * Get whether the given (PDO) exception can be fixed by reconnecting to the database. + * + * @param Exception $err + * + * @return bool + */ + public static function isRetryable(Exception $err): bool + { + $message = $err->getMessage(); + foreach (static::$retryableErrors as $error) { + if (strpos($message, $error) !== false) { + return true; + } + } + + return false; + } +}