From 6bd7f10e54ac78522ecb37f572a0098c05e587e4 Mon Sep 17 00:00:00 2001 From: Cyperghost Date: Wed, 21 Feb 2024 12:05:09 +0100 Subject: [PATCH] Add try-finally block for SELECT FOR UPDATE statement --- .../BackgroundQueueHandler.class.php | 54 +++++++++++-------- 1 file changed, 31 insertions(+), 23 deletions(-) diff --git a/wcfsetup/install/files/lib/system/background/BackgroundQueueHandler.class.php b/wcfsetup/install/files/lib/system/background/BackgroundQueueHandler.class.php index 91eaaa8a3e..0b83c1ffd6 100644 --- a/wcfsetup/install/files/lib/system/background/BackgroundQueueHandler.class.php +++ b/wcfsetup/install/files/lib/system/background/BackgroundQueueHandler.class.php @@ -78,36 +78,44 @@ final class BackgroundQueueHandler extends SingletonFactory } } - WCF::getDB()->beginTransaction(); - $sql = "INSERT INTO wcf1_background_job - (job, time,identifier) - VALUES (?, ?, ?)"; - $statement = WCF::getDB()->prepare($sql); - $sql = "SELECT jobID - FROM wcf1_background_job - WHERE identifier = ? - FOR UPDATE"; - $selectJobStatement = WCF::getDB()->prepare($sql); + $committed = false; + try { + WCF::getDB()->beginTransaction(); + $sql = "INSERT INTO wcf1_background_job + (job, time,identifier) + VALUES (?, ?, ?)"; + $statement = WCF::getDB()->prepare($sql); + $sql = "SELECT jobID + FROM wcf1_background_job + WHERE identifier = ? + FOR UPDATE"; + $selectJobStatement = WCF::getDB()->prepare($sql); - foreach ($jobs as $job) { - $identifier = null; - if ($job instanceof AbstractUniqueBackgroundJob) { - // Check if the job is already in the queue - $selectJobStatement->execute([$job->identifier()]); - $jobID = $selectJobStatement->fetchSingleColumn(); - if ($jobID !== false) { - continue; + foreach ($jobs as $job) { + $identifier = null; + if ($job instanceof AbstractUniqueBackgroundJob) { + // Check if the job is already in the queue + $selectJobStatement->execute([$job->identifier()]); + $jobID = $selectJobStatement->fetchSingleColumn(); + if ($jobID !== false) { + continue; + } + $identifier = $job->identifier(); } - $identifier = $job->identifier(); - } - $statement->execute([ + $statement->execute([ \serialize($job), $time, $identifier - ]); + ]); + } + WCF::getDB()->commitTransaction(); + $committed = true; + } finally { + if (!$committed) { + WCF::getDB()->rollBackTransaction(); + } } - WCF::getDB()->commitTransaction(); } /** -- 2.20.1