Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.
   1  <?php
   2  // This file is part of Moodle - http://moodle.org/
   3  //
   4  // Moodle is free software: you can redistribute it and/or modify
   5  // it under the terms of the GNU General Public License as published by
   6  // the Free Software Foundation, either version 3 of the License, or
   7  // (at your option) any later version.
   8  //
   9  // Moodle is distributed in the hope that it will be useful,
  10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  // GNU General Public License for more details.
  13  //
  14  // You should have received a copy of the GNU General Public License
  15  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  16  
  17  /**
  18   * Delegated database transaction support.
  19   *
  20   * @package    core_dml
  21   * @copyright  2009 Petr Skoda (http://skodak.org)
  22   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23   */
  24  
  25  defined('MOODLE_INTERNAL') || die();
  26  
  27  /**
  28   * Delegated transaction class.
  29   *
  30   * @package    core_dml
  31   * @copyright  2009 Petr Skoda (http://skodak.org)
  32   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  33   */
  34  class moodle_transaction {
  35      /** @var array The debug_backtrace() returned array.*/
  36      private $start_backtrace;
  37      /**@var moodle_database The moodle_database instance.*/
  38      private $database = null;
  39  
  40      /**
  41       * Delegated transaction constructor,
  42       * can be called only from moodle_database class.
  43       * Unfortunately PHP's protected keyword is useless.
  44       * @param moodle_database $database
  45       */
  46      public function __construct($database) {
  47          $this->database = $database;
  48          $this->start_backtrace = debug_backtrace();
  49          array_shift($this->start_backtrace);
  50      }
  51  
  52      /**
  53       * Returns backtrace of the code starting exception.
  54       * @return array
  55       */
  56      public function get_backtrace() {
  57          return $this->start_backtrace;
  58      }
  59  
  60      /**
  61       * Is the delegated transaction already used?
  62       * @return bool true if commit and rollback allowed, false if already done
  63       */
  64      public function is_disposed() {
  65          return empty($this->database);
  66      }
  67  
  68      /**
  69       * Mark transaction as disposed, no more
  70       * commits and rollbacks allowed.
  71       * To be used only from moodle_database class
  72       * @return null
  73       */
  74      public function dispose() {
  75          return $this->database = null;
  76      }
  77  
  78      /**
  79       * Commit delegated transaction.
  80       * The real database commit SQL is executed
  81       * only after committing all delegated transactions.
  82       *
  83       * Incorrect order of nested commits or rollback
  84       * at any level is resulting in rollback of SQL transaction.
  85       *
  86       * @return void
  87       */
  88      public function allow_commit() {
  89          if ($this->is_disposed()) {
  90              throw new dml_transaction_exception('Transactions already disposed', $this);
  91          }
  92          $this->database->commit_delegated_transaction($this);
  93      }
  94  
  95      /**
  96       * Rollback all current delegated transactions.
  97       *
  98       * @param Exception|Throwable $e mandatory exception/throwable
  99       * @return void
 100       */
 101      public function rollback($e) {
 102          if ($this->is_disposed()) {
 103              throw new dml_transaction_exception('Transactions already disposed', $this);
 104          }
 105          $this->database->rollback_delegated_transaction($this, $e);
 106      }
 107  }