Add try-finally block for SELECT FOR UPDATE statement
authorCyperghost <olaf_schmitz_1@t-online.de>
Wed, 21 Feb 2024 11:05:09 +0000 (12:05 +0100)
committerCyperghost <olaf_schmitz_1@t-online.de>
Wed, 21 Feb 2024 11:05:09 +0000 (12:05 +0100)
wcfsetup/install/files/lib/system/background/BackgroundQueueHandler.class.php

index 91eaaa8a3e15c9e674d2c2b1f0353b72242e3cfb..0b83c1ffd6802de7dc66372bb4636bf2b62f2477 100644 (file)
@@ -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();
     }
 
     /**