/** * Force rollback of all delegated transaction. * Does not throw any exceptions and does not log anything. * * This method should be used only from default exception handlers and other * core code. * * @return void */ public function force_transaction_rollback() { if ($this->transactions) { try { $this->rollback_transaction(); } catch (dml_exception $e) { // ignore any sql errors here, the connection might be broken } } // now enable transactions again $this->transactions = array(); $this->force_rollback = false; \core\event\manager::database_transaction_rolledback(); \core\message\manager::database_transaction_rolledback(); }
/** * Call when delegated transaction failed, this rolls back * all delegated transactions up to the top most level. * * In many cases you do not need to call this method manually, * because all open delegated transactions are rolled back * automatically if exceptions not caught. * * @param moodle_transaction $transaction An instance of a moodle_transaction. * @param Exception $e The related exception to this transaction rollback. * @return void This does not return, instead the exception passed in will be rethrown. */ public function rollback_delegated_transaction(moodle_transaction $transaction, Exception $e) { if ($transaction->is_disposed()) { throw new dml_transaction_exception('Transactions already disposed', $transaction); } // mark as disposed so that it can not be used again $transaction->dispose(); // one rollback at any level rollbacks everything $this->force_rollback = true; if (empty($this->transactions) or $transaction !== $this->transactions[count($this->transactions) - 1]) { // this may or may not be a coding problem, better just rethrow the exception, // because we do not want to loose the original $e throw $e; } if (count($this->transactions) == 1) { // only rollback the top most level $this->rollback_transaction(); } array_pop($this->transactions); if (empty($this->transactions)) { // finally top most level rolled back $this->force_rollback = false; \core\event\manager::database_transaction_rolledback(); \core\message\manager::database_transaction_rolledback(); } throw $e; }