Teach AbortOutOfAnyTransaction to clean up partially-started transactions.
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 29 May 2012 03:57:06 +0000 (23:57 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 29 May 2012 03:57:06 +0000 (23:57 -0400)
AbortOutOfAnyTransaction failed to do anything if the state it saw on
entry corresponded to failing partway through StartTransaction.  I fixed
AbortCurrentTransaction to cope with that case way back in commit
60b2444cc3ba037630c9b940c3c9ef01b954b87b, but evidently overlooked that
AbortOutOfAnyTransaction should do likewise.

Back-patch to all supported branches.  It's not clear that this omission
has any more-than-cosmetic consequences, but it's also not clear that it
doesn't, so back-patching seems the least risky choice.

src/backend/access/transam/xact.c

index c71a10e4ea21fbeee273f6f8065b29b3312609ae..5ae46dee9b5168afc5d2e6382d10fb50a878a134 100644 (file)
@@ -3861,7 +3861,24 @@ AbortOutOfAnyTransaction(void)
        switch (s->blockState)
        {
            case TBLOCK_DEFAULT:
-               /* Not in a transaction, do nothing */
+               if (s->state == TRANS_DEFAULT)
+               {
+                   /* Not in a transaction, do nothing */
+               }
+               else
+               {
+                   /*
+                    * We can get here after an error during transaction start
+                    * (state will be TRANS_START).  Need to clean up the
+                    * incompletely started transaction.  First, adjust the
+                    * low-level state to suppress warning message from
+                    * AbortTransaction.
+                    */
+                   if (s->state == TRANS_START)
+                       s->state = TRANS_INPROGRESS;
+                   AbortTransaction();
+                   CleanupTransaction();
+               }
                break;
            case TBLOCK_STARTED:
            case TBLOCK_BEGIN: