forked from leftypol/leftypol
database.php: add retry_on_deadlock utility function
This commit is contained in:
parent
66cb9728b7
commit
5e97b60ebf
1 changed files with 29 additions and 0 deletions
|
@ -6,6 +6,9 @@
|
|||
|
||||
defined('TINYBOARD') or exit;
|
||||
|
||||
// https://dev.mysql.com/doc/mysql-errors/8.0/en/server-error-reference.html
|
||||
const MYSQL_ER_LOCK_DEADLOCK = 1213;
|
||||
|
||||
class PreparedQueryDebug {
|
||||
protected $query, $explain_query = false;
|
||||
|
||||
|
@ -147,6 +150,32 @@ function query($query) {
|
|||
return $pdo->query($query);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $max_retries The maximum number of times the callable may be re-executed on deadlock detection.
|
||||
* @param callable $query_func A callable that executes a query. Must throw a PDOException on deadlocks.
|
||||
* @return mixed The value returned by $query_func.
|
||||
* @throws PDOException Throws once the maximum number of retries have been attempted.
|
||||
*/
|
||||
function retry_on_deadlock(int $max_retries, callable $query_func) {
|
||||
// Add the first original attempt to the max count.
|
||||
$max_retries += 1;
|
||||
$attempt = 0;
|
||||
|
||||
while (true) {
|
||||
$attempt++;
|
||||
|
||||
try {
|
||||
return $query_func();
|
||||
} catch (\PDOException $e) {
|
||||
if ($e->errorInfo === null || $e->errorInfo[1] != MYSQL_ER_LOCK_DEADLOCK || $attempt >= $max_retries) {
|
||||
throw $e;
|
||||
}
|
||||
// Wait for 0.5s before retrying...
|
||||
usleep(500000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function db_error($PDOStatement = null) {
|
||||
global $pdo, $db_error;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue