@ -190,6 +190,7 @@ typedef struct TransactionStateData
bool startedInRecovery ; /* did we start in recovery? */
bool didLogXid ; /* has xid been included in WAL record? */
int parallelModeLevel ; /* Enter/ExitParallelMode counter */
bool chain ; /* start a new block after this one */
struct TransactionStateData * parent ; /* back link to parent */
} TransactionStateData ;
@ -2775,6 +2776,36 @@ StartTransactionCommand(void)
MemoryContextSwitchTo ( CurTransactionContext ) ;
}
/*
* Simple system for saving and restoring transaction characteristics
* ( isolation level , read only , deferrable ) . We need this for transaction
* chaining , so that we can set the characteristics of the new transaction to
* be the same as the previous one . ( We need something like this because the
* GUC system resets the characteristics at transaction end , so for example
* just skipping the reset in StartTransaction ( ) won ' t work . )
*/
static int save_XactIsoLevel ;
static bool save_XactReadOnly ;
static bool save_XactDeferrable ;
void
SaveTransactionCharacteristics ( void )
{
save_XactIsoLevel = XactIsoLevel ;
save_XactReadOnly = XactReadOnly ;
save_XactDeferrable = XactDeferrable ;
}
void
RestoreTransactionCharacteristics ( void )
{
XactIsoLevel = save_XactIsoLevel ;
XactReadOnly = save_XactReadOnly ;
XactDeferrable = save_XactDeferrable ;
}
/*
* CommitTransactionCommand
*/
@ -2783,6 +2814,9 @@ CommitTransactionCommand(void)
{
TransactionState s = CurrentTransactionState ;
if ( s - > chain )
SaveTransactionCharacteristics ( ) ;
switch ( s - > blockState )
{
/*
@ -2834,6 +2868,13 @@ CommitTransactionCommand(void)
case TBLOCK_END :
CommitTransaction ( ) ;
s - > blockState = TBLOCK_DEFAULT ;
if ( s - > chain )
{
StartTransaction ( ) ;
s - > blockState = TBLOCK_INPROGRESS ;
s - > chain = false ;
RestoreTransactionCharacteristics ( ) ;
}
break ;
/*
@ -2853,6 +2894,13 @@ CommitTransactionCommand(void)
case TBLOCK_ABORT_END :
CleanupTransaction ( ) ;
s - > blockState = TBLOCK_DEFAULT ;
if ( s - > chain )
{
StartTransaction ( ) ;
s - > blockState = TBLOCK_INPROGRESS ;
s - > chain = false ;
RestoreTransactionCharacteristics ( ) ;
}
break ;
/*
@ -2864,6 +2912,13 @@ CommitTransactionCommand(void)
AbortTransaction ( ) ;
CleanupTransaction ( ) ;
s - > blockState = TBLOCK_DEFAULT ;
if ( s - > chain )
{
StartTransaction ( ) ;
s - > blockState = TBLOCK_INPROGRESS ;
s - > chain = false ;
RestoreTransactionCharacteristics ( ) ;
}
break ;
/*
@ -3521,7 +3576,7 @@ PrepareTransactionBlock(const char *gid)
bool result ;
/* Set up to commit the current transaction */
result = EndTransactionBlock ( ) ;
result = EndTransactionBlock ( false ) ;
/* If successful, change outer tblock state to PREPARE */
if ( result )
@ -3567,7 +3622,7 @@ PrepareTransactionBlock(const char *gid)
* resource owner , etc while executing inside a Portal .
*/
bool
EndTransactionBlock ( void )
EndTransactionBlock ( bool chain )
{
TransactionState s = CurrentTransactionState ;
bool result = false ;
@ -3693,6 +3748,13 @@ EndTransactionBlock(void)
break ;
}
Assert ( s - > blockState = = TBLOCK_STARTED | |
s - > blockState = = TBLOCK_END | |
s - > blockState = = TBLOCK_ABORT_END | |
s - > blockState = = TBLOCK_ABORT_PENDING ) ;
s - > chain = chain ;
return result ;
}
@ -3703,7 +3765,7 @@ EndTransactionBlock(void)
* As above , we don ' t actually do anything here except change blockState .
*/
void
UserAbortTransactionBlock ( void )
UserAbortTransactionBlock ( bool chain )
{
TransactionState s = CurrentTransactionState ;
@ -3801,6 +3863,11 @@ UserAbortTransactionBlock(void)
BlockStateAsString ( s - > blockState ) ) ;
break ;
}
Assert ( s - > blockState = = TBLOCK_ABORT_END | |
s - > blockState = = TBLOCK_ABORT_PENDING ) ;
s - > chain = chain ;
}
/*