From 6abc6ae7d1d5c3b86e4c3fb41e7578134d740e54 Mon Sep 17 00:00:00 2001 From: dimitr Date: Thu, 19 Feb 2015 14:43:26 +0000 Subject: [PATCH] 1) Fixed CORE-4382: User savepoints are not released on commit. 2) Respect the "no-auto-undo" option when retaining a transaction context. Thanks to Dimitry Sibiryakov. --- src/jrd/tra.cpp | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/src/jrd/tra.cpp b/src/jrd/tra.cpp index 00041c6853..8829c3e6b7 100644 --- a/src/jrd/tra.cpp +++ b/src/jrd/tra.cpp @@ -399,7 +399,14 @@ void TRA_commit(thread_db* tdbb, jrd_tra* transaction, const bool retaining_flag // Flush pages if transaction logically modified data if (transaction->tra_flags & TRA_write) + { + // Get rid of user savepoints to allow intermediate garbage collection + // in indices and BLOBs after in-place updates + while (transaction->tra_save_point && (transaction->tra_save_point->sav_flags & SAV_user)) + VIO_verb_cleanup(tdbb, transaction); + transaction_flush(tdbb, FLUSH_TRAN, transaction->tra_number); + } else if ((transaction->tra_flags & (TRA_prepare2 | TRA_reconnected)) || (sysTran->tra_flags & TRA_write)) { @@ -1317,11 +1324,13 @@ void TRA_rollback(thread_db* tdbb, jrd_tra* transaction, const bool retaining_fl VIO_verb_cleanup(tdbb, transaction); transaction->tra_save_point = next; } + if (transaction->tra_save_point) { if (!(transaction->tra_save_point->sav_flags & SAV_trans_level)) BUGCHECK(287); // Too many savepoints - // This transaction savepoint contains wrong data now. Clean it up + + // This transaction savepoint contains wrong data now, clean it up VIO_verb_cleanup(tdbb, transaction); // get rid of transaction savepoint } } @@ -2429,7 +2438,7 @@ static void retain_context(thread_db* tdbb, jrd_tra* transaction, bool commit, i // savepoint and possibly start a new transaction-level savepoint. // Get rid of all user savepoints - // Why we can do this in reverse order described in commit method + // Why we can do this in reverse order described in TRA_rollback() while (transaction->tra_save_point && (transaction->tra_save_point->sav_flags & SAV_user)) { Savepoint* const next = transaction->tra_save_point->sav_next; @@ -2442,9 +2451,15 @@ static void retain_context(thread_db* tdbb, jrd_tra* transaction, bool commit, i { if (!(transaction->tra_save_point->sav_flags & SAV_trans_level)) BUGCHECK(287); // Too many savepoints + VIO_verb_cleanup(tdbb, transaction); // get rid of transaction savepoint - VIO_start_save_point(tdbb, transaction); // start new savepoint - transaction->tra_save_point->sav_flags |= SAV_trans_level; + + if (!(transaction->tra_flags & TRA_no_auto_undo)) + { + // start new transaction savepoint + VIO_start_save_point(tdbb, transaction); + transaction->tra_save_point->sav_flags |= SAV_trans_level; + } } if (transaction->tra_flags & TRA_precommitted)