8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-23 07:23:04 +01:00

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.
This commit is contained in:
dimitr 2015-02-19 14:43:26 +00:00
parent 0b56909d92
commit 6abc6ae7d1

View File

@ -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)