aboutsummaryrefslogtreecommitdiff
path: root/src/backend/access/transam/xact.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/access/transam/xact.c')
-rw-r--r--src/backend/access/transam/xact.c23
1 files changed, 22 insertions, 1 deletions
diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c
index a8fbd043ae5..5e7e8122003 100644
--- a/src/backend/access/transam/xact.c
+++ b/src/backend/access/transam/xact.c
@@ -4226,6 +4226,9 @@ AbortOutOfAnyTransaction(void)
{
TransactionState s = CurrentTransactionState;
+ /* Ensure we're not running in a doomed memory context */
+ AtAbort_Memory();
+
/*
* Get out of any transaction or nested transaction
*/
@@ -4267,7 +4270,14 @@ AbortOutOfAnyTransaction(void)
break;
case TBLOCK_ABORT:
case TBLOCK_ABORT_END:
- /* AbortTransaction already done, still need Cleanup */
+
+ /*
+ * AbortTransaction is already done, still need Cleanup.
+ * However, if we failed partway through running ROLLBACK,
+ * there will be an active portal running that command, which
+ * we need to shut down before doing CleanupTransaction.
+ */
+ AtAbort_Portals();
CleanupTransaction();
s->blockState = TBLOCK_DEFAULT;
break;
@@ -4290,6 +4300,14 @@ AbortOutOfAnyTransaction(void)
case TBLOCK_SUBABORT_END:
case TBLOCK_SUBABORT_RESTART:
/* As above, but AbortSubTransaction already done */
+ if (s->curTransactionOwner)
+ {
+ /* As in TBLOCK_ABORT, might have a live portal to zap */
+ AtSubAbort_Portals(s->subTransactionId,
+ s->parent->subTransactionId,
+ s->curTransactionOwner,
+ s->parent->curTransactionOwner);
+ }
CleanupSubTransaction();
s = CurrentTransactionState; /* changed by pop */
break;
@@ -4298,6 +4316,9 @@ AbortOutOfAnyTransaction(void)
/* Should be out of all subxacts now */
Assert(s->parent == NULL);
+
+ /* If we didn't actually have anything to do, revert to TopMemoryContext */
+ AtCleanup_Memory();
}
/*