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 1ad826d18f3..150a0e89140 100644
--- a/src/backend/access/transam/xact.c
+++ b/src/backend/access/transam/xact.c
@@ -4208,6 +4208,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
*/
@@ -4249,7 +4252,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;
@@ -4272,6 +4282,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;
@@ -4280,6 +4298,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();
}
/*