/** * Call this method from test if you want to make sure that * the resetting of database is done the slow way without transaction * rollback. * * This is useful especially when testing stuff that is not compatible with transactions. * * @return void */ public function preventResetByRollback() { if ($this->testdbtransaction and !$this->testdbtransaction->is_disposed()) { $this->testdbtransaction->allow_commit(); $this->testdbtransaction = null; } }
/** * 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|Throwable $e The related exception/throwable 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, $e) { if (!$e instanceof Exception && !$e instanceof Throwable) { // PHP7 - we catch Throwables in phpunit but can't use that as the type hint in PHP5. $e = new \coding_exception("Must be given an Exception or Throwable object!"); } 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; }
/** * 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; } throw $e; }