diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c
index c7251e9207320a0580a1d3130c8966297bf4a746..e6767d4c4b1829095347e5fd1c89047708d59c7f 100644
--- a/src/backend/access/transam/xact.c
+++ b/src/backend/access/transam/xact.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.155 2003/09/28 23:26:20 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.156 2003/10/16 16:50:41 tgl Exp $
  *
  * NOTES
  *		Transaction aborts can now occur two ways:
@@ -202,7 +202,7 @@ static TransactionStateData CurrentTransactionStateData = {
 								 * perspective */
 };
 
-TransactionState CurrentTransactionState = &CurrentTransactionStateData;
+static TransactionState CurrentTransactionState = &CurrentTransactionStateData;
 
 /*
  *	User-tweakable parameters
@@ -826,20 +826,11 @@ StartTransaction(void)
 {
 	TransactionState s = CurrentTransactionState;
 
-	FreeXactSnapshot();
-	XactIsoLevel = DefaultXactIsoLevel;
-	XactReadOnly = DefaultXactReadOnly;
-
 	/*
-	 * Check the current transaction state.  If the transaction system is
-	 * switched off, or if we're already in a transaction, do nothing.
-	 * We're already in a transaction when the monitor sends a null
-	 * command to the backend to flush the comm channel.  This is a hacky
-	 * fix to a communications problem, and we keep having to deal with it
-	 * here.  We should fix the comm channel code.	mao 080891
+	 * check the current transaction state
 	 */
-	if (s->state == TRANS_INPROGRESS)
-		return;
+	if (s->state != TRANS_DEFAULT)
+		elog(WARNING, "StartTransaction and not in default state");
 
 	/*
 	 * set the current transaction state information appropriately during
@@ -847,6 +838,13 @@ StartTransaction(void)
 	 */
 	s->state = TRANS_START;
 
+	/*
+	 * Make sure we've freed any old snapshot, and reset xact state variables
+	 */
+	FreeXactSnapshot();
+	XactIsoLevel = DefaultXactIsoLevel;
+	XactReadOnly = DefaultXactReadOnly;
+
 	/*
 	 * generate a new transaction id
 	 */
@@ -1725,6 +1723,24 @@ IsTransactionBlock(void)
 	return true;
 }
 
+/*
+ * IsTransactionOrTransactionBlock --- are we within either a transaction
+ * or a transaction block?  (The backend is only really "idle" when this
+ * returns false.)
+ *
+ * This should match up with IsTransactionBlock and IsTransactionState.
+ */
+bool
+IsTransactionOrTransactionBlock(void)
+{
+	TransactionState s = CurrentTransactionState;
+
+	if (s->blockState == TBLOCK_DEFAULT && s->state == TRANS_DEFAULT)
+		return false;
+
+	return true;
+}
+
 /*
  * TransactionBlockStatusCode - return status code to send in ReadyForQuery
  */
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index d977995f5ff084a0c701010f922ac397ae7769ca..f0dde27bb178dd9e576095632e24d87fbd5527ea 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.101 2003/10/01 21:30:52 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.102 2003/10/16 16:50:41 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -91,10 +91,6 @@
 #include "utils/syscache.h"
 
 
-/* stuff that we really ought not be touching directly :-( */
-extern TransactionState CurrentTransactionState;
-
-
 /*
  * State for outbound notifies consists of a list of all relnames NOTIFYed
  * in the current transaction.	We do not actually perform a NOTIFY until
@@ -717,7 +713,7 @@ Async_NotifyHandler(SIGNAL_ARGS)
 void
 EnableNotifyInterrupt(void)
 {
-	if (CurrentTransactionState->blockState != TRANS_DEFAULT)
+	if (IsTransactionOrTransactionBlock())
 		return;					/* not really idle */
 
 	/*
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index 9c0af0d238bd32f815ad629e341ff256455644f0..ea247487e2c55213b550ac6ceaf0ccd05c6097ba 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.372 2003/10/09 02:40:18 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.373 2003/10/16 16:50:41 tgl Exp $
  *
  * NOTES
  *	  this is the "main" module of the postgres backend and
@@ -2660,7 +2660,7 @@ PostgresMain(int argc, char *argv[], const char *username)
 	if (!IsUnderPostmaster)
 	{
 		puts("\nPOSTGRES backend interactive interface ");
-		puts("$Revision: 1.372 $ $Date: 2003/10/09 02:40:18 $\n");
+		puts("$Revision: 1.373 $ $Date: 2003/10/16 16:50:41 $\n");
 	}
 
 	/*
@@ -2796,7 +2796,7 @@ PostgresMain(int argc, char *argv[], const char *username)
 		{
 			pgstat_report_tabstat();
 
-			if (IsTransactionBlock())
+			if (IsTransactionOrTransactionBlock())
 			{
 				set_ps_display("idle in transaction");
 				pgstat_report_activity("<IDLE> in transaction");
diff --git a/src/include/access/xact.h b/src/include/access/xact.h
index 466249fedadc2872ab22a3a6babea1acb90cb68b..d95c3df794586a1b20b87fd70c32c373846ca921 100644
--- a/src/include/access/xact.h
+++ b/src/include/access/xact.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: xact.h,v 1.56 2003/09/28 23:26:20 tgl Exp $
+ * $Id: xact.h,v 1.57 2003/10/16 16:50:41 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -129,6 +129,7 @@ extern void AbortCurrentTransaction(void);
 extern void BeginTransactionBlock(void);
 extern void EndTransactionBlock(void);
 extern bool IsTransactionBlock(void);
+extern bool IsTransactionOrTransactionBlock(void);
 extern char TransactionBlockStatusCode(void);
 extern void UserAbortTransactionBlock(void);
 extern void AbortOutOfAnyTransaction(void);