diff -u b/core/lib/Drupal/Core/Cache/DatabaseBackend.php b/core/lib/Drupal/Core/Cache/DatabaseBackend.php --- b/core/lib/Drupal/Core/Cache/DatabaseBackend.php +++ b/core/lib/Drupal/Core/Cache/DatabaseBackend.php @@ -141,26 +141,23 @@ * Implements Drupal\Core\Cache\CacheBackendInterface::set(). */ public function set($cid, $data, $expire = CacheBackendInterface::CACHE_PERMANENT, array $tags = array()) { - // This is the first try. - $try = 1; - // Maximum one tries. - $max = 1; - // This loop is necessary to make sure any exceptions thrown in doSet() - // are propagated back with a proper backtrace. Putting the second doSet() - // within the catch would result in "Additional exception thrown while - // handling an exception". - do { - try { - $this->doSet($cid, $data, $expire, $tags); + $try_again = FALSE; + try { + // The bin might not yet exist. + $this->doSet($cid, $data, $expire, $tags); + } + catch (\Exception $e) { + // If there was an exception, try to create the bins. + if (!$try_again = $this->ensureBinExists()) { + // If the exception happened for other reason than the missing bin + // table, propagate the exception. + throw $e; } - catch (\Exception $e) { - if ($this->ensureBinExists()) { - // If the bin was just created, try one more time but only one more. - // By using try - max we avoid an infinite loop. - $max = 2; - } - } - } while ($try++ < $max); + } + // Now that the bin has been created, try again if necessary. + if ($try_again) { + $this->doSet($cid, $data, $expire, $tags); + } } /**