diff -cr cvs/src/backend/access/transam/xact.c cvs.build/src/backend/access/transam/xact.c
*** cvs/src/backend/access/transam/xact.c	2009-12-24 13:55:12.000000000 +0100
--- cvs.build/src/backend/access/transam/xact.c	2009-12-24 20:55:17.000000000 +0100
***************
*** 2692,2697 ****
--- 2692,2735 ----
  }
  
  /*
+  *	AbortAnyTransaction
+  */
+ void
+ AbortAnyTransaction(void)
+ {
+ 	TransactionState s = CurrentTransactionState;
+ 
+ 	switch (s->blockState)
+ 	{
+ 		case TBLOCK_DEFAULT:
+ 		case TBLOCK_STARTED:
+ 		case TBLOCK_BEGIN:
+ 		case TBLOCK_INPROGRESS:
+ 		case TBLOCK_END:
+ 		case TBLOCK_ABORT:
+ 		case TBLOCK_SUBABORT:
+ 		case TBLOCK_ABORT_END:
+ 		case TBLOCK_ABORT_PENDING:
+ 		case TBLOCK_PREPARE:
+ 		case TBLOCK_SUBABORT_END:
+ 		case TBLOCK_SUBABORT_RESTART:
+ 			AbortCurrentTransaction();
+ 			break;
+ 
+ 		case TBLOCK_SUBINPROGRESS:
+ 		case TBLOCK_SUBBEGIN:
+ 		case TBLOCK_SUBEND:
+ 		case TBLOCK_SUBABORT_PENDING:
+ 		case TBLOCK_SUBRESTART:
+ 			AbortSubTransaction();
+ 			CleanupSubTransaction();
+ 			AbortAnyTransaction();
+ 			break;
+ 	}
+ }
+ 
+ 
+ /*
   *	PreventTransactionChain
   *
   *	This routine is to be called by statements that must not run inside
diff -cr cvs/src/backend/tcop/postgres.c cvs.build/src/backend/tcop/postgres.c
*** cvs/src/backend/tcop/postgres.c	2009-12-24 13:55:18.000000000 +0100
--- cvs.build/src/backend/tcop/postgres.c	2009-12-24 20:55:17.000000000 +0100
***************
*** 2637,2643 ****
  	if (!proc_exit_inprogress)
  	{
  		InterruptPending = true;
! 		QueryCancelPending = true;
  
  		/*
  		 * If it's safe to interrupt, and we're waiting for a lock, service
--- 2637,2647 ----
  	if (!proc_exit_inprogress)
  	{
  		InterruptPending = true;
! 
! 		if (DoingCommandRead)
! 			TransactionCancelPending = true;
! 		else
! 			QueryCancelPending = true;
  
  		/*
  		 * If it's safe to interrupt, and we're waiting for a lock, service
***************
*** 2789,2794 ****
--- 2793,2821 ----
  					 errmsg("canceling statement due to user request")));
  		}
  	}
+ 	if (TransactionCancelPending)
+ 	{
+ 		QueryCancelPending = false;
+ 		ImmediateInterruptOK = false;	/* not idle anymore */
+ 
+ 		if (!IsTransactionOrTransactionBlock())
+ 			return;
+ 
+ 		if (IsAbortedTransactionBlockState())
+ 			return;
+ 
+ 		DisableNotifyInterrupt();
+ 		DisableCatchupInterrupt();
+ 
+ 		ereport(NOTICE,
+ 				(errcode(ERRCODE_QUERY_CANCELED),
+ 				 errmsg("canceling transaction due to user request")));
+ 
+ 		AbortAnyTransaction();
+ 
+ 		set_ps_display("idle in transaction (aborted)", false);
+ 		pgstat_report_activity("<IDLE> in transaction (aborted)");
+ 	}
  	/* If we get here, do nothing (probably, QueryCancelPending was reset) */
  }
  
diff -cr cvs/src/backend/utils/init/globals.c cvs.build/src/backend/utils/init/globals.c
*** cvs/src/backend/utils/init/globals.c	2009-12-09 11:24:42.000000000 +0100
--- cvs.build/src/backend/utils/init/globals.c	2009-12-24 20:55:17.000000000 +0100
***************
*** 27,32 ****
--- 27,33 ----
  
  volatile bool InterruptPending = false;
  volatile bool QueryCancelPending = false;
+ volatile bool TransactionCancelPending = false;
  volatile bool ProcDiePending = false;
  volatile bool ImmediateInterruptOK = false;
  volatile uint32 InterruptHoldoffCount = 0;
diff -cr cvs/src/include/access/xact.h cvs.build/src/include/access/xact.h
*** cvs/src/include/access/xact.h	2009-12-24 13:55:28.000000000 +0100
--- cvs.build/src/include/access/xact.h	2009-12-24 20:55:17.000000000 +0100
***************
*** 204,209 ****
--- 204,210 ----
  extern bool IsTransactionOrTransactionBlock(void);
  extern char TransactionBlockStatusCode(void);
  extern void AbortOutOfAnyTransaction(void);
+ extern void AbortAnyTransaction(void);
  extern void PreventTransactionChain(bool isTopLevel, const char *stmtType);
  extern void RequireTransactionChain(bool isTopLevel, const char *stmtType);
  extern bool IsInTransactionChain(bool isTopLevel);
diff -cr cvs/src/include/miscadmin.h cvs.build/src/include/miscadmin.h
*** cvs/src/include/miscadmin.h	2009-12-24 13:55:28.000000000 +0100
--- cvs.build/src/include/miscadmin.h	2009-12-24 20:55:37.000000000 +0100
***************
*** 68,73 ****
--- 68,74 ----
  /* these are marked volatile because they are set by signal handlers: */
  extern PGDLLIMPORT volatile bool InterruptPending;
  extern volatile bool QueryCancelPending;
+ extern volatile bool TransactionCancelPending;
  extern volatile bool ProcDiePending;
  
  /* these are marked volatile because they are examined by signal handlers: */