8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-22 18:43:02 +01:00

Fixed #7052: Races between transactions on the primary side may cause update conflicts while applying journals to the replica

This commit is contained in:
Dmitry Yemanov 2021-12-01 12:21:29 +03:00
parent fd6bf8d404
commit 056a261492
2 changed files with 8 additions and 6 deletions

View File

@ -31,6 +31,7 @@
#include "../jrd/ods_proto.h"
#include "../jrd/tpc_proto.h"
#include "../jrd/tra_proto.h"
#include "../jrd/replication/Publisher.h"
#include "../common/isc_proto.h"
#include <sys/stat.h>
@ -601,6 +602,7 @@ CommitNumber TipCache::snapshotState(thread_db* tdbb, TraNumber number)
// to avoid more work in the future
if (state == tra_active)
{
REPL_trans_cleanup(tdbb, number);
TRA_set_state(tdbb, 0, number, tra_dead); // This will update TIP cache
return CN_DEAD;
}

View File

@ -530,8 +530,8 @@ void TRA_commit(thread_db* tdbb, jrd_tra* transaction, const bool retaining_flag
// Set the state on the inventory page to be committed
TRA_set_state(tdbb, transaction, transaction->tra_number, tra_committed);
REPL_trans_commit(tdbb, transaction);
TRA_set_state(tdbb, transaction, transaction->tra_number, tra_committed);
// Perform any post commit work
@ -1458,8 +1458,8 @@ void TRA_rollback(thread_db* tdbb, jrd_tra* transaction, const bool retaining_fl
return;
}
TRA_set_state(tdbb, transaction, transaction->tra_number, state);
REPL_trans_rollback(tdbb, transaction);
TRA_set_state(tdbb, transaction, transaction->tra_number, state);
TRA_release_transaction(tdbb, transaction, &trace);
}
@ -1995,8 +1995,8 @@ int TRA_wait(thread_db* tdbb, jrd_tra* trans, TraNumber number, jrd_tra::wait_t
if (state == tra_active)
{
state = tra_dead;
TRA_set_state(tdbb, 0, number, tra_dead);
REPL_trans_cleanup(tdbb, number);
TRA_set_state(tdbb, 0, number, tra_dead);
}
// If the transaction disappeared into limbo, died, for constructively
@ -2632,13 +2632,13 @@ static void retain_context(thread_db* tdbb, jrd_tra* transaction, bool commit, i
if (!dbb->readOnly())
{
// Set the state on the inventory page
TRA_set_state(tdbb, transaction, old_number, state);
if (commit)
REPL_trans_commit(tdbb, transaction);
else
REPL_trans_rollback(tdbb, transaction);
// Set the state on the inventory page
TRA_set_state(tdbb, transaction, old_number, state);
}
if (dbb->dbb_config->getClearGTTAtRetaining())
release_temp_tables(tdbb, transaction);