@@ -89,7 +89,7 @@ typedef Firebird::GenericMap<Firebird::Pair<Firebird::NonPooled<USHORT, UCHAR> >
8989#ifdef SUPERSERVER_V2
9090static TraNumber bump_transaction_id (thread_db*, WIN*);
9191#else
92- static header_page* bump_transaction_id (thread_db*, WIN*);
92+ static header_page* bump_transaction_id (thread_db*, WIN*, bool );
9393#endif
9494static void retain_context (thread_db* tdbb, jrd_tra* transaction, bool commit, int state);
9595static void expand_view_lock (thread_db* tdbb, jrd_tra*, jrd_rel*, UCHAR lock_type,
@@ -1445,16 +1445,24 @@ void TRA_set_state(thread_db* tdbb, jrd_tra* transaction, TraNumber number, int
14451445 WIN window (DB_PAGE_SPACE, -1 );
14461446 tx_inv_page* tip = fetch_inventory_page (tdbb, &window, sequence, LCK_write);
14471447
1448+ UCHAR* address = tip->tip_transactions + byte;
1449+ const int old_state = ((*address) >> shift) & TRA_MASK;
1450+
14481451#ifdef SUPERSERVER_V2
14491452 CCH_MARK (tdbb, &window);
14501453 const ULONG generation = tip->tip_header .pag_generation ;
14511454#else
1452- CCH_MARK_MUST_WRITE (tdbb, &window);
1455+ if (!(dbb->dbb_flags & DBB_shared) || transaction->tra_flags & TRA_write ||
1456+ old_state != tra_active || state != tra_committed)
1457+ {
1458+ CCH_MARK_MUST_WRITE (tdbb, &window);
1459+ }
1460+ else
1461+ CCH_MARK (tdbb, &window);
14531462#endif
14541463
14551464 // set the state on the TIP page
14561465
1457- UCHAR* address = tip->tip_transactions + byte;
14581466 *address &= ~(TRA_MASK << shift);
14591467 *address |= state << shift;
14601468
@@ -1944,7 +1952,7 @@ static TraNumber bump_transaction_id(thread_db* tdbb, WIN* window)
19441952#else
19451953
19461954
1947- static header_page* bump_transaction_id (thread_db* tdbb, WIN* window)
1955+ static header_page* bump_transaction_id (thread_db* tdbb, WIN* window, bool dontWrite )
19481956{
19491957/* *************************************
19501958 *
@@ -1999,7 +2007,11 @@ static header_page* bump_transaction_id(thread_db* tdbb, WIN* window)
19992007
20002008 // Extend, if necessary, has apparently succeeded. Next, update header page
20012009
2002- CCH_MARK_MUST_WRITE (tdbb, window);
2010+ if (dontWrite && !new_tip)
2011+ CCH_MARK (tdbb, window);
2012+ else
2013+ CCH_MARK_MUST_WRITE (tdbb, window);
2014+
20032015 dbb->dbb_next_transaction = number;
20042016
20052017 Ods::writeNT (header, number);
@@ -2391,7 +2403,10 @@ static void retain_context(thread_db* tdbb, jrd_tra* transaction, bool commit, i
23912403 new_number = dbb->dbb_next_transaction + dbb->generateTransactionId (tdbb);
23922404 else
23932405 {
2394- const header_page* const header = bump_transaction_id (tdbb, &window);
2406+ const bool dontWrite = (dbb->dbb_flags & DBB_shared) &&
2407+ (transaction->tra_flags & TRA_readonly);
2408+
2409+ const header_page* const header = bump_transaction_id (tdbb, &window, dontWrite);
23952410 new_number = Ods::getNT (header);
23962411 }
23972412#endif
@@ -3077,7 +3092,10 @@ static void transaction_start(thread_db* tdbb, jrd_tra* trans)
30773092 }
30783093 else
30793094 {
3080- const header_page* header = bump_transaction_id (tdbb, &window);
3095+ const bool dontWrite = (dbb->dbb_flags & DBB_shared) &&
3096+ (trans->tra_flags & TRA_readonly);
3097+
3098+ const header_page* header = bump_transaction_id (tdbb, &window, dontWrite);
30813099 number = Ods::getNT (header);
30823100 oldest = Ods::getOIT (header);
30833101 oldest_active = Ods::getOAT (header);
0 commit comments