* XactLockTableWait * * Wait for the specified transaction to commit or abort. If an operation * is specified, an error context callback is set up. If 'oper' is passed as * None, no error context callback is set up. * * Note that this does the right thing for subtransactions: if we wait on a * subtransaction, we will exit as soon as it aborts or its top parent commits. * It takes some e
| 674 | * and if so wait for its parent. |
| 675 | */ |
| 676 | void |
| 677 | XactLockTableWait(TransactionId xid, Relation rel, ItemPointer ctid, |
| 678 | XLTW_Oper oper) |
| 679 | { |
| 680 | LOCKTAG tag; |
| 681 | XactLockTableWaitInfo info; |
| 682 | ErrorContextCallback callback; |
| 683 | bool first = true; |
| 684 | |
| 685 | /* |
| 686 | * Concurrent update and delete will wait on segment when GDD is enabled (or |
| 687 | * the corner case that utility mode delete|update in segment which does not hold |
| 688 | * gxid), need to report the waited transactions to QD to make sure the they have |
| 689 | * the same transaction order on the master. |
| 690 | */ |
| 691 | if (Gp_role == GP_ROLE_EXECUTE) |
| 692 | { |
| 693 | MemoryContext oldContext; |
| 694 | DistributedTransactionId gxid = LocalXidGetDistributedXid(xid); |
| 695 | |
| 696 | if (gxid != InvalidDistributedTransactionId) |
| 697 | { |
| 698 | /* |
| 699 | * allocate waitGxids in TopMemoryContext since it's used in |
| 700 | * 'commit prepared' and the TopTransactionContext has been delete |
| 701 | * after 'prepare' |
| 702 | */ |
| 703 | oldContext = MemoryContextSwitchTo(TopMemoryContext); |
| 704 | MyTmGxactLocal->waitGxids = lappend_int(MyTmGxactLocal->waitGxids, gxid); |
| 705 | MemoryContextSwitchTo(oldContext); |
| 706 | } |
| 707 | } |
| 708 | |
| 709 | /* |
| 710 | * If an operation is specified, set up our verbose error context |
| 711 | * callback. |
| 712 | */ |
| 713 | if (oper != XLTW_None) |
| 714 | { |
| 715 | Assert(RelationIsValid(rel)); |
| 716 | Assert(ItemPointerIsValid(ctid)); |
| 717 | |
| 718 | info.rel = rel; |
| 719 | info.ctid = ctid; |
| 720 | info.oper = oper; |
| 721 | |
| 722 | callback.callback = XactLockTableWaitErrorCb; |
| 723 | callback.arg = &info; |
| 724 | callback.previous = error_context_stack; |
| 725 | error_context_stack = &callback; |
| 726 | } |
| 727 | |
| 728 | for (;;) |
| 729 | { |
| 730 | Assert(TransactionIdIsValid(xid)); |
| 731 | Assert(!TransactionIdEquals(xid, GetTopTransactionIdIfAny())); |
| 732 | |
| 733 | SET_LOCKTAG_TRANSACTION(tag, xid); |
no test coverage detected