diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index ab4c72762d..648ad4a846 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -2182,6 +2182,8 @@ asyncQueueAdvanceTail(void)
 static void
 ProcessIncomingNotify(bool flush)
 {
+	MemoryContext oldcontext;
+
 	/* We *must* reset the flag */
 	notifyInterruptPending = false;
 
@@ -2196,14 +2198,21 @@ ProcessIncomingNotify(bool flush)
 
 	/*
 	 * We must run asyncQueueReadAllNotifications inside a transaction, else
-	 * bad things happen if it gets an error.
+	 * bad things happen if it gets an error.  However, we need to preserve
+	 * the caller's memory context (typically MessageContext).
 	 */
+	oldcontext = CurrentMemoryContext;
+
 	StartTransactionCommand();
 
 	asyncQueueReadAllNotifications();
 
 	CommitTransactionCommand();
 
+	/* Caller's context had better not have been transaction-local */
+	Assert(MemoryContextIsValid(oldcontext));
+	MemoryContextSwitchTo(oldcontext);
+
 	/*
 	 * If this isn't an end-of-command case, we must flush the notify messages
 	 * to ensure frontend gets them promptly.
diff --git a/src/backend/storage/ipc/sinval.c b/src/backend/storage/ipc/sinval.c
index d9b16f84d1..4e69015fe4 100644
--- a/src/backend/storage/ipc/sinval.c
+++ b/src/backend/storage/ipc/sinval.c
@@ -16,6 +16,7 @@
 
 #include "access/xact.h"
 #include "miscadmin.h"
+#include "nodes/memnodes.h"
 #include "storage/latch.h"
 #include "storage/sinvaladt.h"
 #include "utils/inval.h"
@@ -182,6 +183,7 @@ ProcessCatchupInterrupt(void)
 		 * can just call AcceptInvalidationMessages() to do this.  If we
 		 * aren't, we start and immediately end a transaction; the call to
 		 * AcceptInvalidationMessages() happens down inside transaction start.
+		 * Be sure to preserve caller's memory context when we do that.
 		 *
 		 * It is awfully tempting to just call AcceptInvalidationMessages()
 		 * without the rest of the xact start/stop overhead, and I think that
@@ -195,9 +197,14 @@ ProcessCatchupInterrupt(void)
 		}
 		else
 		{
+			MemoryContext oldcontext = CurrentMemoryContext;
+
 			elog(DEBUG4, "ProcessCatchupEvent outside transaction");
 			StartTransactionCommand();
 			CommitTransactionCommand();
+			/* Caller's context had better not have been transaction-local */
+			Assert(MemoryContextIsValid(oldcontext));
+			MemoryContextSwitchTo(oldcontext);
 		}
 	}
 }
