]> granicus.if.org Git - postgresql/commitdiff
Teach AbortOutOfAnyTransaction to clean up partially-started transactions.
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 29 May 2012 03:57:14 +0000 (23:57 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 29 May 2012 03:57:14 +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 b34b418fd983907f8a373555a770bf2c3048c390..184fe28f5c53c602f35a52e1d680254cb50e9644 100644 (file)
@@ -3802,7 +3802,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: