From a1dda107bd1d96fd467d044eee3de7833764238e Mon Sep 17 00:00:00 2001 From: skodak Date: Fri, 12 Jun 2009 07:55:44 +0000 Subject: [PATCH] MDL-19470 detection of nested transactions, only one level allowed --- lib/dml/adodb_moodle_database.php | 9 ++++++ lib/dml/moodle_database.php | 35 +++++++++++++++++++++-- lib/dml/mysqli_native_moodle_database.php | 9 ++++++ lib/dml/oci_native_moodle_database.php | 15 ++++++++-- lib/dml/pdo_moodle_database.php | 9 ++++++ lib/dml/pgsql_native_moodle_database.php | 9 ++++++ 6 files changed, 80 insertions(+), 6 deletions(-) diff --git a/lib/dml/adodb_moodle_database.php b/lib/dml/adodb_moodle_database.php index 9a033bf494..e32444c057 100644 --- a/lib/dml/adodb_moodle_database.php +++ b/lib/dml/adodb_moodle_database.php @@ -508,14 +508,23 @@ abstract class adodb_moodle_database extends moodle_database { } public function begin_sql() { + if (!parent::begin_sql()) { + return false; + } $this->adodb->BeginTrans(); return true; } public function commit_sql() { + if (!parent::commit_sql()) { + return false; + } $this->adodb->CommitTrans(); return true; } public function rollback_sql() { + if (!parent::rollback_sql()) { + return false; + } $this->adodb->RollbackTrans(); return true; } diff --git a/lib/dml/moodle_database.php b/lib/dml/moodle_database.php index e8070348ff..d773531061 100644 --- a/lib/dml/moodle_database.php +++ b/lib/dml/moodle_database.php @@ -79,6 +79,9 @@ abstract class moodle_database { protected $used_for_db_sessions = false; + /** Flag indicating transaction in progress */ + protected $intransaction = false; + /** internal temporary variable */ private $fix_sql_params_i; @@ -248,6 +251,9 @@ abstract class moodle_database { * Do NOT use connect() again, create a new instance if needed. */ public function dispose() { + if ($this->intransaction) { + error_log('Active database transaction detected when disposing database!'); // probably can not write to console anymore, log problem instead + } if ($this->used_for_db_sessions) { // this is needed because we need to save session to db before closing it session_get_instance()->write_close(); @@ -1739,23 +1745,46 @@ abstract class moodle_database { * you'll need to ensure you call commit_sql() or your changes *will* be lost. * * this is _very_ useful for massive updates + * + * Please note only one level of transactions is supported, please do not use + * transaction in moodle core! Transaction are intended for web services + * enrolment and auth synchronisation scripts, etc. + * + * @return bool success */ public function begin_sql() { - return false; + if ($this->intransaction) { + debugging('Transaction already in progress'); + return false; + } + $this->intransaction = true; + return true; } /** * on DBs that support it, commit the transaction + * @return bool success */ public function commit_sql() { - return false; + if (!$this->intransaction) { + debugging('Transaction not in progress'); + return false; + } + $this->intransaction = false; + return true; } /** * on DBs that support it, rollback the transaction + * @return bool success */ public function rollback_sql() { - return false; + if (!$this->intransaction) { + debugging('Transaction not in progress'); + return false; + } + $this->intransaction = false; + return true; } /// session locking diff --git a/lib/dml/mysqli_native_moodle_database.php b/lib/dml/mysqli_native_moodle_database.php index 12871c106f..ef5d08b74e 100644 --- a/lib/dml/mysqli_native_moodle_database.php +++ b/lib/dml/mysqli_native_moodle_database.php @@ -956,6 +956,9 @@ class mysqli_native_moodle_database extends moodle_database { * this is _very_ useful for massive updates */ public function begin_sql() { + if (!parent::begin_sql()) { + return false; + } $sql = "SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED"; $this->query_start($sql, NULL, SQL_QUERY_AUX); $result = $this->mysqli->query($sql); @@ -973,6 +976,9 @@ class mysqli_native_moodle_database extends moodle_database { * on DBs that support it, commit the transaction */ public function commit_sql() { + if (!parent::commit_sql()) { + return false; + } $sql = "COMMIT"; $this->query_start($sql, NULL, SQL_QUERY_AUX); $result = $this->mysqli->query($sql); @@ -985,6 +991,9 @@ class mysqli_native_moodle_database extends moodle_database { * on DBs that support it, rollback the transaction */ public function rollback_sql() { + if (!parent::rollback_sql()) { + return false; + } $sql = "ROLLBACK"; $this->query_start($sql, NULL, SQL_QUERY_AUX); $result = $this->mysqli->query($sql); diff --git a/lib/dml/oci_native_moodle_database.php b/lib/dml/oci_native_moodle_database.php index 04a2aa6301..9a586cd6d6 100644 --- a/lib/dml/oci_native_moodle_database.php +++ b/lib/dml/oci_native_moodle_database.php @@ -1215,7 +1215,10 @@ class oci_native_moodle_database extends moodle_database { * this is _very_ useful for massive updates */ public function begin_sql() { - return false; + if (!parent::begin_sql()) { + return false; + } + return true; $sql = "BEGIN"; $this->query_start($sql, NULL, SQL_QUERY_AUX); @@ -1230,7 +1233,10 @@ class oci_native_moodle_database extends moodle_database { * on DBs that support it, commit the transaction */ public function commit_sql() { - return false; + if (!parent::commit_sql()) { + return false; + } + return true; $sql = "COMMIT"; $this->query_start($sql, NULL, SQL_QUERY_AUX); @@ -1245,7 +1251,10 @@ class oci_native_moodle_database extends moodle_database { * on DBs that support it, rollback the transaction */ public function rollback_sql() { - return false; + if (!parent::rollback_sql()) { + return false; + } + return true; $sql = "ROLLBACK"; $this->query_start($sql, NULL, SQL_QUERY_AUX); diff --git a/lib/dml/pdo_moodle_database.php b/lib/dml/pdo_moodle_database.php index 294174696e..b88cebd947 100644 --- a/lib/dml/pdo_moodle_database.php +++ b/lib/dml/pdo_moodle_database.php @@ -525,6 +525,9 @@ abstract class pdo_moodle_database extends moodle_database { } public function begin_sql() { + if (!parent::begin_sql()) { + return false; + } try { $this->pdb->beginTransaction(); return true; @@ -533,6 +536,9 @@ abstract class pdo_moodle_database extends moodle_database { } } public function commit_sql() { + if (!parent::commit_sql()) { + return false; + } try { $this->pdb->commit(); return true; @@ -542,6 +548,9 @@ abstract class pdo_moodle_database extends moodle_database { } public function rollback_sql() { + if (!parent::rollback_sql()) { + return false; + } try { $this->pdb->rollBack(); return true; diff --git a/lib/dml/pgsql_native_moodle_database.php b/lib/dml/pgsql_native_moodle_database.php index a2999a873d..288f44b4eb 100644 --- a/lib/dml/pgsql_native_moodle_database.php +++ b/lib/dml/pgsql_native_moodle_database.php @@ -1107,6 +1107,9 @@ class pgsql_native_moodle_database extends moodle_database { * this is _very_ useful for massive updates */ public function begin_sql() { + if (!parent::begin_sql()) { + return false; + } $sql = "BEGIN ISOLATION LEVEL READ COMMITTED"; $this->query_start($sql, NULL, SQL_QUERY_AUX); $result = pg_query($this->pgsql, $sql); @@ -1120,6 +1123,9 @@ class pgsql_native_moodle_database extends moodle_database { * on DBs that support it, commit the transaction */ public function commit_sql() { + if (!parent::commit_sql()) { + return false; + } $sql = "COMMIT"; $this->query_start($sql, NULL, SQL_QUERY_AUX); $result = pg_query($this->pgsql, $sql); @@ -1133,6 +1139,9 @@ class pgsql_native_moodle_database extends moodle_database { * on DBs that support it, rollback the transaction */ public function rollback_sql() { + if (!parent::rollback_sql()) { + return false; + } $sql = "ROLLBACK"; $this->query_start($sql, NULL, SQL_QUERY_AUX); $result = pg_query($this->pgsql, $sql); -- 2.39.5