| 2575 | |
| 2576 | |
| 2577 | static void retain_context(thread_db* tdbb, jrd_tra* transaction, bool commit, int state) |
| 2578 | { |
| 2579 | /************************************** |
| 2580 | * |
| 2581 | * r e t a i n _ c o n t e x t |
| 2582 | * |
| 2583 | ************************************** |
| 2584 | * |
| 2585 | * Functional description |
| 2586 | * If 'commit' flag is true, commit the transaction, |
| 2587 | * else rollback the transaction. |
| 2588 | * |
| 2589 | * Commit/rollback a transaction while preserving the |
| 2590 | * context, in particular, its snapshot. The |
| 2591 | * trick is to insure that the transaction's |
| 2592 | * oldest active is seen by other transactions |
| 2593 | * simultaneously starting up. |
| 2594 | * |
| 2595 | **************************************/ |
| 2596 | SET_TDBB(tdbb); |
| 2597 | Database* dbb = tdbb->getDatabase(); |
| 2598 | CHECK_DBB(dbb); |
| 2599 | |
| 2600 | // All savepoints must already be released in TRA_commit/TRA_rollback |
| 2601 | fb_assert(!transaction->tra_save_point); |
| 2602 | |
| 2603 | // The new transaction needs to remember the 'commit-retained' transaction |
| 2604 | // because it must see the operations of the 'commit-retained' transaction and |
| 2605 | // its snapshot doesn't contain these operations. |
| 2606 | |
| 2607 | if (commit) |
| 2608 | TBM_SET(tdbb->getDefaultPool(), &transaction->tra_commit_sub_trans, transaction->tra_number); |
| 2609 | |
| 2610 | // Create a new transaction lock, inheriting oldest active from transaction being committed. |
| 2611 | |
| 2612 | WIN window(DB_PAGE_SPACE, -1); |
| 2613 | TraNumber new_number; |
| 2614 | #ifdef SUPERSERVER_V2 |
| 2615 | new_number = bump_transaction_id(tdbb, &window); |
| 2616 | #else |
| 2617 | if (dbb->readOnly()) |
| 2618 | new_number = dbb->generateTransactionId(); |
| 2619 | else |
| 2620 | { |
| 2621 | const bool dontWrite = (dbb->dbb_flags & DBB_shared) && |
| 2622 | (transaction->tra_flags & TRA_readonly); |
| 2623 | |
| 2624 | const header_page* const header = bump_transaction_id(tdbb, &window, dontWrite); |
| 2625 | new_number = Ods::getNT(header); |
| 2626 | } |
| 2627 | #endif |
| 2628 | |
| 2629 | Lock* new_lock = NULL; |
| 2630 | Lock* old_lock = transaction->tra_lock; |
| 2631 | if (old_lock) |
| 2632 | { |
| 2633 | new_lock = FB_NEW_RPT(*tdbb->getDefaultPool(), 0) Lock(tdbb, sizeof(TraNumber), LCK_tra); |
| 2634 | new_lock->setKey(new_number); |
no test coverage detected