| 672 | } |
| 673 | |
| 674 | CommitNumber TipCache::snapshotState(thread_db* tdbb, TraNumber number) |
| 675 | { |
| 676 | // Can only be called on initialized TipCache |
| 677 | fb_assert(m_tpcHeader); |
| 678 | |
| 679 | // Get data from cache |
| 680 | CommitNumber stateCn = cacheState(number); |
| 681 | |
| 682 | // Transaction is committed or dead? |
| 683 | if (stateCn == CN_DEAD || (stateCn >= CN_PREHISTORIC && stateCn <= CN_MAX_NUMBER)) |
| 684 | return stateCn; |
| 685 | |
| 686 | // We excluded all other cases above |
| 687 | fb_assert(stateCn == CN_ACTIVE || stateCn == CN_LIMBO); |
| 688 | |
| 689 | // Query lock data for a transaction; if we can then we know it is still active. |
| 690 | // |
| 691 | // This logic differs from original TPC implementation as follows: |
| 692 | // 1. We use read_data instead of taking a lock, to avoid possible race conditions |
| 693 | // (they were probably not causing much harm, but consistency is a good thing) |
| 694 | // 2. Old TPC returned tra_active for transactions in limbo, which was not correct |
| 695 | // |
| 696 | // hvlad: tra_active is correct here as it allows caller to wait for prepared but |
| 697 | // still active transaction |
| 698 | Lock temp_lock(tdbb, sizeof(TraNumber), LCK_tra); |
| 699 | temp_lock.setKey(number); |
| 700 | |
| 701 | if (LCK_read_data(tdbb, &temp_lock)) |
| 702 | return CN_ACTIVE; |
| 703 | |
| 704 | // Go to disk, and obtain state of our transaction from TIP |
| 705 | int state = TRA_fetch_state(tdbb, number); |
| 706 | |
| 707 | // We already know for sure that this transaction cannot be active, so mark it dead now |
| 708 | // to avoid more work in the future |
| 709 | if (state == tra_active) |
| 710 | { |
| 711 | REPL_trans_cleanup(tdbb, number); |
| 712 | TRA_set_state(tdbb, 0, number, tra_dead); // This will update TIP cache |
| 713 | return CN_DEAD; |
| 714 | } |
| 715 | |
| 716 | // Update cache and return new state |
| 717 | stateCn = setState(number, state); |
| 718 | return stateCn; |
| 719 | } |
| 720 | |
| 721 | void TipCache::updateOldestTransaction(thread_db *tdbb, TraNumber oldest, TraNumber oldestSnapshot) |
| 722 | { |
no test coverage detected