Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 40126ac

Browse files
committed
Refactoring for CommitTransactionCommand()/AbortCurrentTransaction()
fefd9a3 turned tail recursion of CommitTransactionCommand() and AbortCurrentTransaction() into iteration. However, it splits the handling of cases between different functions. This commit puts the handling of all the cases into AbortCurrentTransactionInternal() and CommitTransactionCommandInternal(). Now CommitTransactionCommand() and AbortCurrentTransaction() are just doing the repeated calls of internal functions. Reported-by: Andres Freund Discussion: https://postgr.es/m/20240415224834.w6piwtefskoh32mv%40awork3.anarazel.de Author: Andres Freund
1 parent 3ab8cf9 commit 40126ac

File tree

1 file changed

+71
-84
lines changed
  • src/backend/access/transam

1 file changed

+71
-84
lines changed

src/backend/access/transam/xact.c

+71-84
Original file line numberDiff line numberDiff line change
@@ -346,8 +346,8 @@ static void CommitTransaction(void);
346346
static TransactionId RecordTransactionAbort(bool isSubXact);
347347
static void StartTransaction(void);
348348

349-
static void CommitTransactionCommandInternal(void);
350-
static void AbortCurrentTransactionInternal(void);
349+
static bool CommitTransactionCommandInternal(void);
350+
static bool AbortCurrentTransactionInternal(void);
351351

352352
static void StartSubTransaction(void);
353353
static void CommitSubTransaction(void);
@@ -3092,50 +3092,27 @@ RestoreTransactionCharacteristics(const SavedTransactionCharacteristics *s)
30923092
void
30933093
CommitTransactionCommand(void)
30943094
{
3095-
while (true)
3095+
/*
3096+
* Repeatedly call CommitTransactionCommandInternal() until all the work
3097+
* is done.
3098+
*/
3099+
while (!CommitTransactionCommandInternal())
30963100
{
3097-
switch (CurrentTransactionState->blockState)
3098-
{
3099-
/*
3100-
* The current already-failed subtransaction is ending due to
3101-
* a ROLLBACK or ROLLBACK TO command, so pop it and
3102-
* recursively examine the parent (which could be in any of
3103-
* several states).
3104-
*/
3105-
case TBLOCK_SUBABORT_END:
3106-
CleanupSubTransaction();
3107-
continue;
3108-
3109-
/*
3110-
* As above, but it's not dead yet, so abort first.
3111-
*/
3112-
case TBLOCK_SUBABORT_PENDING:
3113-
AbortSubTransaction();
3114-
CleanupSubTransaction();
3115-
continue;
3116-
default:
3117-
break;
3118-
}
3119-
CommitTransactionCommandInternal();
3120-
break;
31213101
}
31223102
}
31233103

31243104
/*
3125-
* CommitTransactionCommandInternal - a function doing all the material work
3126-
* regarding handling the commit transaction command except for loop over
3127-
* subtransactions.
3105+
* CommitTransactionCommandInternal - a function doing an iteration of work
3106+
* regarding handling the commit transaction command. In the case of
3107+
* subtransactions more than one iterations could be required. Returns
3108+
* true when no more iterations required, false otherwise.
31283109
*/
3129-
static void
3110+
static bool
31303111
CommitTransactionCommandInternal(void)
31313112
{
31323113
TransactionState s = CurrentTransactionState;
31333114
SavedTransactionCharacteristics savetc;
31343115

3135-
/* This states are handled in CommitTransactionCommand() */
3136-
Assert(s->blockState != TBLOCK_SUBABORT_END &&
3137-
s->blockState != TBLOCK_SUBABORT_PENDING);
3138-
31393116
/* Must save in case we need to restore below */
31403117
SaveTransactionCharacteristics(&savetc);
31413118

@@ -3319,6 +3296,25 @@ CommitTransactionCommandInternal(void)
33193296
BlockStateAsString(s->blockState));
33203297
break;
33213298

3299+
/*
3300+
* The current already-failed subtransaction is ending due to a
3301+
* ROLLBACK or ROLLBACK TO command, so pop it and recursively
3302+
* examine the parent (which could be in any of several states).
3303+
* As we need to examine the parent, return false to request the
3304+
* caller to do the next iteration.
3305+
*/
3306+
case TBLOCK_SUBABORT_END:
3307+
CleanupSubTransaction();
3308+
return false;
3309+
3310+
/*
3311+
* As above, but it's not dead yet, so abort first.
3312+
*/
3313+
case TBLOCK_SUBABORT_PENDING:
3314+
AbortSubTransaction();
3315+
CleanupSubTransaction();
3316+
return false;
3317+
33223318
/*
33233319
* The current subtransaction is the target of a ROLLBACK TO
33243320
* command. Abort and pop it, then start a new subtransaction
@@ -3376,10 +3372,10 @@ CommitTransactionCommandInternal(void)
33763372
s->blockState = TBLOCK_SUBINPROGRESS;
33773373
}
33783374
break;
3379-
default:
3380-
/* Keep compiler quiet */
3381-
break;
33823375
}
3376+
3377+
/* Done, no more iterations required */
3378+
return true;
33833379
}
33843380

33853381
/*
@@ -3390,59 +3386,26 @@ CommitTransactionCommandInternal(void)
33903386
void
33913387
AbortCurrentTransaction(void)
33923388
{
3393-
while (true)
3389+
/*
3390+
* Repeatedly call AbortCurrentTransactionInternal() until all the work is
3391+
* done.
3392+
*/
3393+
while (!AbortCurrentTransactionInternal())
33943394
{
3395-
switch (CurrentTransactionState->blockState)
3396-
{
3397-
/*
3398-
* If we failed while trying to create a subtransaction, clean
3399-
* up the broken subtransaction and abort the parent. The
3400-
* same applies if we get a failure while ending a
3401-
* subtransaction.
3402-
*/
3403-
case TBLOCK_SUBBEGIN:
3404-
case TBLOCK_SUBRELEASE:
3405-
case TBLOCK_SUBCOMMIT:
3406-
case TBLOCK_SUBABORT_PENDING:
3407-
case TBLOCK_SUBRESTART:
3408-
AbortSubTransaction();
3409-
CleanupSubTransaction();
3410-
continue;
3411-
3412-
/*
3413-
* Same as above, except the Abort() was already done.
3414-
*/
3415-
case TBLOCK_SUBABORT_END:
3416-
case TBLOCK_SUBABORT_RESTART:
3417-
CleanupSubTransaction();
3418-
continue;
3419-
default:
3420-
break;
3421-
}
3422-
AbortCurrentTransactionInternal();
3423-
break;
34243395
}
34253396
}
34263397

34273398
/*
3428-
* AbortCurrentTransactionInternal - a function doing all the material work
3429-
* regarding handling the abort transaction command except for loop over
3430-
* subtransactions.
3399+
* AbortCurrentTransactionInternal - a function doing an iteration of work
3400+
* regarding handling the current transaction abort. In the case of
3401+
* subtransactions more than one iterations could be required. Returns
3402+
* true when no more iterations required, false otherwise.
34313403
*/
3432-
static void
3404+
static bool
34333405
AbortCurrentTransactionInternal(void)
34343406
{
34353407
TransactionState s = CurrentTransactionState;
34363408

3437-
/* This states are handled in AbortCurrentTransaction() */
3438-
Assert(s->blockState != TBLOCK_SUBBEGIN &&
3439-
s->blockState != TBLOCK_SUBRELEASE &&
3440-
s->blockState != TBLOCK_SUBCOMMIT &&
3441-
s->blockState != TBLOCK_SUBABORT_PENDING &&
3442-
s->blockState != TBLOCK_SUBRESTART &&
3443-
s->blockState != TBLOCK_SUBABORT_END &&
3444-
s->blockState != TBLOCK_SUBABORT_RESTART);
3445-
34463409
switch (s->blockState)
34473410
{
34483411
case TBLOCK_DEFAULT:
@@ -3563,10 +3526,34 @@ AbortCurrentTransactionInternal(void)
35633526
AbortSubTransaction();
35643527
s->blockState = TBLOCK_SUBABORT;
35653528
break;
3566-
default:
3567-
/* Keep compiler quiet */
3568-
break;
3529+
3530+
/*
3531+
* If we failed while trying to create a subtransaction, clean up
3532+
* the broken subtransaction and abort the parent. The same
3533+
* applies if we get a failure while ending a subtransaction. As
3534+
* we need to abort the parent, return false to request the caller
3535+
* to do the next iteration.
3536+
*/
3537+
case TBLOCK_SUBBEGIN:
3538+
case TBLOCK_SUBRELEASE:
3539+
case TBLOCK_SUBCOMMIT:
3540+
case TBLOCK_SUBABORT_PENDING:
3541+
case TBLOCK_SUBRESTART:
3542+
AbortSubTransaction();
3543+
CleanupSubTransaction();
3544+
return false;
3545+
3546+
/*
3547+
* Same as above, except the Abort() was already done.
3548+
*/
3549+
case TBLOCK_SUBABORT_END:
3550+
case TBLOCK_SUBABORT_RESTART:
3551+
CleanupSubTransaction();
3552+
return false;
35693553
}
3554+
3555+
/* Done, no more iterations required */
3556+
return true;
35703557
}
35713558

35723559
/*

0 commit comments

Comments
 (0)