public function finishWrite() { if ($this->readOnly) { return; } elseif (is_null($this->currentLang)) { throw new MWException(__CLASS__ . ': must call startWrite() before finishWrite()'); } $this->dbw->startAtomic(__METHOD__); try { $this->dbw->delete('l10n_cache', ['lc_lang' => $this->currentLang], __METHOD__); foreach (array_chunk($this->batch, 500) as $rows) { $this->dbw->insert('l10n_cache', $rows, __METHOD__); } $this->writesDone = true; } catch (DBQueryError $e) { if ($this->dbw->wasReadOnlyError()) { $this->readOnly = true; // just avoid site down time } else { throw $e; } } $this->dbw->endAtomic(__METHOD__); $this->currentLang = null; $this->batch = []; }
/** * Handle a DBQueryError which occurred during a write operation. * * @param DBError $exception * @param IDatabase|null $db DB handle or null if connection failed * @param int $serverIndex * @throws Exception */ protected function handleWriteError(DBError $exception, IDatabase $db = null, $serverIndex) { if (!$db) { $this->markServerDown($exception, $serverIndex); } elseif ($db->wasReadOnlyError()) { if ($db->trxLevel() && $this->usesMainDB()) { // Errors like deadlocks and connection drops already cause rollback. // For consistency, we have no choice but to throw an error and trigger // complete rollback if the main DB is also being used as the cache DB. throw $exception; } } $this->logger->error("DBError: {$exception->getMessage()}"); if ($exception instanceof DBConnectionError) { $this->setLastError(BagOStuff::ERR_UNREACHABLE); $this->logger->debug(__METHOD__ . ": ignoring connection error"); } else { $this->setLastError(BagOStuff::ERR_UNEXPECTED); $this->logger->debug(__METHOD__ . ": ignoring query error"); } }