diff options
Diffstat (limited to 'src/backend/access/transam/xact.c')
-rw-r--r-- | src/backend/access/transam/xact.c | 23 |
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(); } /* |