Changeset: bca0b4f5b042 https://sourceforge.net/p/mrbs/hg-code/ci/bca0b4f5b0420ece2f144aa3117c6ca4b8a946d9 Author: Campbell Morrison <cimorri...@hg.code.sf.net> Date: Wed Apr 05 23:09:31 2017 +0100 Log message:
Fixed transaction problems. See SF Support Requests #977. diffstat: web/edit_entry_handler.php | 10 ++++++++++ web/lib/MRBS/DB.php | 22 +++++++++++++++++++--- web/lib/MRBS/DB_mysql.php | 5 +---- web/lib/MRBS/DB_pgsql.php | 16 ++++++++++------ web/mrbs_sql.inc | 11 +---------- 5 files changed, 41 insertions(+), 23 deletions(-) diffs (172 lines): diff -r 0b445cca4b04 -r bca0b4f5b042 web/edit_entry_handler.php --- a/web/edit_entry_handler.php Wed Apr 05 22:25:56 2017 +0100 +++ b/web/edit_entry_handler.php Wed Apr 05 23:09:31 2017 +0100 @@ -714,7 +714,15 @@ // Wrap the editing process in a transaction, because if deleting the old booking should fail for // some reason then we'll potentially be left with two overlapping bookings. A deletion could fail // if, for example, the database user hasn't been granted DELETE rights. + +// Acquire mutex to lock out others trying to book the same slot(s). +if (!db()->mutex_lock($tbl_entry)) +{ + fatal_error(get_vocab("failed_to_acquire")); +} + db()->begin(); + $transaction_ok = true; $result = mrbsMakeBookings($bookings, $this_id, $just_check, $skip, $original_room_id, $send_mail, $edit_type); @@ -736,6 +744,8 @@ trigger_error('Edit failed.', E_USER_WARNING); } +db()->mutex_unlock($tbl_entry); + // If this is an Ajax request, output the result and finish if ($ajax && function_exists('json_encode')) diff -r 0b445cca4b04 -r bca0b4f5b042 web/lib/MRBS/DB.php --- a/web/lib/MRBS/DB.php Wed Apr 05 22:25:56 2017 +0100 +++ b/web/lib/MRBS/DB.php Wed Apr 05 23:09:31 2017 +0100 @@ -194,14 +194,20 @@ // (Only applies to persistent connections, but we'll do it for all cases to keep // things simple) mrbs_ignore_user_abort(TRUE); - $this->dbh->beginTransaction(); + if (!$this->dbh->inTransaction()) + { + $this->dbh->beginTransaction(); + } } // Commit (end) a transaction. See begin(). public function commit() { - $this->dbh->commit(); + if ($this->dbh->inTransaction()) + { + $this->dbh->commit(); + } mrbs_ignore_user_abort(FALSE); } @@ -209,9 +215,19 @@ // Roll back a transaction, aborting it. See begin(). public function rollback() { - $this->dbh->rollBack(); + if ($this->dbh->inTransaction()) + { + $this->dbh->rollBack(); + } mrbs_ignore_user_abort(FALSE); } + + + // Checks if inside a transaction + public function inTransaction() + { + return $this->dbh->inTransaction(); + } // Return a string identifying the database version diff -r 0b445cca4b04 -r bca0b4f5b042 web/lib/MRBS/DB_mysql.php --- a/web/lib/MRBS/DB_mysql.php Wed Apr 05 22:25:56 2017 +0100 +++ b/web/lib/MRBS/DB_mysql.php Wed Apr 05 23:09:31 2017 +0100 @@ -98,10 +98,7 @@ } // Rollback any outstanding transactions - if ($this->dbh->inTransaction()) - { - $this->rollback(); - } + $this->rollback(); } diff -r 0b445cca4b04 -r bca0b4f5b042 web/lib/MRBS/DB_pgsql.php --- a/web/lib/MRBS/DB_pgsql.php Wed Apr 05 22:25:56 2017 +0100 +++ b/web/lib/MRBS/DB_pgsql.php Wed Apr 05 23:09:31 2017 +0100 @@ -79,7 +79,11 @@ { try { - $this->command("BEGIN"); + // LOCK TABLE can only be used in transaction blocks + if (!$this->dbh->inTransaction()) + { + $this->begin(); + } $this->command("LOCK TABLE $name IN EXCLUSIVE MODE"); } catch (DBException $e) @@ -98,7 +102,10 @@ // is no other way. public function mutex_unlock($name) { - $this->command("COMMIT"); + if ($this->dbh->inTransaction()) + { + $this->commit(); + } $this->mutex_lock_name = NULL; } @@ -115,10 +122,7 @@ } // Rollback any outstanding transactions - if ($this->dbh->inTransaction()) - { - $this->rollback(); - } + $this->rollback(); } diff -r 0b445cca4b04 -r bca0b4f5b042 web/mrbs_sql.inc --- a/web/mrbs_sql.inc Wed Apr 05 22:25:56 2017 +0100 +++ b/web/mrbs_sql.inc Wed Apr 05 23:09:31 2017 +0100 @@ -1763,7 +1763,7 @@ function mrbsMakeBookings($bookings, $id=NULL, $just_check=FALSE, $skip=FALSE, $original_room_id=NULL, $send_mail=FALSE, $edit_type='') { global $max_rep_entrys, $enable_periods, $resolution, $mail_settings; - global $tbl_entry, $tbl_room, $tbl_area; + global $tbl_room, $tbl_area; // All the data, except for the status and room id, will be common // across the bookings @@ -1820,12 +1820,6 @@ $repeat_id = NULL; } - // Acquire mutex to lock out others trying to book the same slot(s). - if (!db()->mutex_lock($tbl_entry)) - { - fatal_error(get_vocab("failed_to_acquire")); - } - // Validate the booking for (a) conflicting bookings and (b) conformance to policy rules $valid_booking = TRUE; $conflicts = array(); // Holds a list of all the conflicts @@ -1968,7 +1962,6 @@ // booking, then stop here and return the results if ($just_check || !$valid_booking) { - db()->mutex_unlock($tbl_entry); return $result; } @@ -2097,8 +2090,6 @@ } } } // end foreach $bookings - - db()->mutex_unlock($tbl_entry); $result['new_details'] = $new_details; $result['slots'] = intval(($common['end_time'] - $common['start_time'])/$resolution); ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot _______________________________________________ Mrbs-commits mailing list Mrbs-commits@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mrbs-commits