diff --git a/doc/src/sgml/ref/create_subscription.sgml b/doc/src/sgml/ref/create_subscription.sgml
index 59e5ad0..6480690 100644
--- a/doc/src/sgml/ref/create_subscription.sgml
+++ b/doc/src/sgml/ref/create_subscription.sgml
@@ -47,8 +47,9 @@ CREATE SUBSCRIPTION <replaceable class="PARAMETER">subscription_name</replaceabl
   </para>
 
   <para>
-   A logical replication worker will be started to replicate data for the new
-   subscription at the commit of the transaction where this command is run.
+   <command>CREATE SUBSCRIPTION</command> cannot be executed inside a
+   transaction block. A logical replication worker will be started to replicate
+   data for the new subscription at the end of this command.
   </para>
 
   <para>
diff --git a/doc/src/sgml/ref/drop_subscription.sgml b/doc/src/sgml/ref/drop_subscription.sgml
index 9f2fb93..17235ad 100644
--- a/doc/src/sgml/ref/drop_subscription.sgml
+++ b/doc/src/sgml/ref/drop_subscription.sgml
@@ -38,8 +38,8 @@ DROP SUBSCRIPTION [ IF EXISTS ] <replaceable class="parameter">name</replaceable
   </para>
 
   <para>
-   The replication worker associated with the subscription will not stop until
-   after the transaction that issued this command has committed.
+   <command>DROP SUBSCRIPTION</command> cannot be executed inside a
+   transaction block.
   </para>
  </refsect1>
 
diff --git a/src/backend/commands/subscriptioncmds.c b/src/backend/commands/subscriptioncmds.c
index ab21e64..1779719 100644
--- a/src/backend/commands/subscriptioncmds.c
+++ b/src/backend/commands/subscriptioncmds.c
@@ -18,6 +18,7 @@
 
 #include "access/heapam.h"
 #include "access/htup_details.h"
+#include "access/xact.h"
 
 #include "catalog/indexing.h"
 #include "catalog/objectaccess.h"
@@ -204,7 +205,7 @@ publicationListToArray(List *publist)
  * Create new subscription.
  */
 ObjectAddress
-CreateSubscription(CreateSubscriptionStmt *stmt)
+CreateSubscription(CreateSubscriptionStmt *stmt, bool isTopLevel)
 {
 	Relation	rel;
 	ObjectAddress myself;
@@ -221,6 +222,12 @@ CreateSubscription(CreateSubscriptionStmt *stmt)
 	bool		create_slot;
 	List	   *publications;
 
+	/*
+	 * We cannot run CREATE SUBSCRIPTION inside a user transaction
+	 * block.
+	 */
+	PreventTransactionChain(isTopLevel, "CREATE SUBSCRIPTION");
+
 	if (!superuser())
 		ereport(ERROR,
 				(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
@@ -424,7 +431,7 @@ AlterSubscription(AlterSubscriptionStmt *stmt)
  * Drop a subscription
  */
 void
-DropSubscription(DropSubscriptionStmt *stmt)
+DropSubscription(DropSubscriptionStmt *stmt, bool isTopLevel)
 {
 	Relation	rel;
 	ObjectAddress myself;
@@ -441,6 +448,12 @@ DropSubscription(DropSubscriptionStmt *stmt)
 	WalReceiverConn	   *wrconn = NULL;
 	StringInfoData		cmd;
 
+	/*
+	 * We cannot run DROP SUBSCRIPTION inside a user transaction
+	 * block.
+	 */
+	PreventTransactionChain(isTopLevel, "DROP SUBSCRIPTION");
+
 	rel = heap_open(SubscriptionRelationId, RowExclusiveLock);
 
 	tup = SearchSysCache2(SUBSCRIPTIONNAME, MyDatabaseId,
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index 3bc0ae5..20b5273 100644
--- a/src/backend/tcop/utility.c
+++ b/src/backend/tcop/utility.c
@@ -1609,7 +1609,8 @@ ProcessUtilitySlow(ParseState *pstate,
 				break;
 
 			case T_CreateSubscriptionStmt:
-				address = CreateSubscription((CreateSubscriptionStmt *) parsetree);
+				address = CreateSubscription((CreateSubscriptionStmt *) parsetree,
+											 isTopLevel);
 				break;
 
 			case T_AlterSubscriptionStmt:
@@ -1617,7 +1618,7 @@ ProcessUtilitySlow(ParseState *pstate,
 				break;
 
 			case T_DropSubscriptionStmt:
-				DropSubscription((DropSubscriptionStmt *) parsetree);
+				DropSubscription((DropSubscriptionStmt *) parsetree, isTopLevel);
 				/* no commands stashed for DROP */
 				commandCollected = true;
 				break;
diff --git a/src/include/commands/subscriptioncmds.h b/src/include/commands/subscriptioncmds.h
index 127696c..1765879 100644
--- a/src/include/commands/subscriptioncmds.h
+++ b/src/include/commands/subscriptioncmds.h
@@ -18,9 +18,10 @@
 #include "catalog/objectaddress.h"
 #include "nodes/parsenodes.h"
 
-extern ObjectAddress CreateSubscription(CreateSubscriptionStmt *stmt);
+extern ObjectAddress CreateSubscription(CreateSubscriptionStmt *stmt,
+										bool isTopLevel);
 extern ObjectAddress AlterSubscription(AlterSubscriptionStmt *stmt);
-extern void DropSubscription(DropSubscriptionStmt *stmt);
+extern void DropSubscription(DropSubscriptionStmt *stmt, bool isTopLevel);
 
 extern ObjectAddress AlterSubscriptionOwner(const char *name, Oid newOwnerId);
 extern void AlterSubscriptionOwner_oid(Oid subid, Oid newOwnerId);
