⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xact.c

📁 postgresql8.3.4源码,开源数据库
💻 C
📖 第 1 页 / 共 5 页
字号:
	 * GID is invalid or already in use.	 */	gxact = MarkAsPreparing(xid, prepareGID, prepared_at,							GetUserId(), MyDatabaseId);	prepareGID = NULL;	/*	 * Collect data for the 2PC state file.  Note that in general, no actual	 * state change should happen in the called modules during this step,	 * since it's still possible to fail before commit, and in that case we	 * want transaction abort to be able to clean up.  (In particular, the	 * AtPrepare routines may error out if they find cases they cannot	 * handle.)  State cleanup should happen in the PostPrepare routines	 * below.  However, some modules can go ahead and clear state here because	 * they wouldn't do anything with it during abort anyway.	 *	 * Note: because the 2PC state file records will be replayed in the same	 * order they are made, the order of these calls has to match the order in	 * which we want things to happen during COMMIT PREPARED or ROLLBACK	 * PREPARED; in particular, pay attention to whether things should happen	 * before or after releasing the transaction's locks.	 */	StartPrepare(gxact);	AtPrepare_Notify();	AtPrepare_UpdateFlatFiles();	AtPrepare_Inval();	AtPrepare_Locks();	AtPrepare_PgStat();	/*	 * Here is where we really truly prepare.	 *	 * We have to record transaction prepares even if we didn't make any	 * updates, because the transaction manager might get confused if we lose	 * a global transaction.	 */	EndPrepare(gxact);	/*	 * Now we clean up backend-internal state and release internal resources.	 */	/* Reset XactLastRecEnd until the next transaction writes something */	XactLastRecEnd.xrecoff = 0;	/*	 * Let others know about no transaction in progress by me.	This has to be	 * done *after* the prepared transaction has been marked valid, else	 * someone may think it is unlocked and recyclable.	 */	ProcArrayClearTransaction(MyProc);	/*	 * This is all post-transaction cleanup.  Note that if an error is raised	 * here, it's too late to abort the transaction.  This should be just	 * noncritical resource releasing.	See notes in CommitTransaction.	 */	CallXactCallbacks(XACT_EVENT_PREPARE);	ResourceOwnerRelease(TopTransactionResourceOwner,						 RESOURCE_RELEASE_BEFORE_LOCKS,						 true, true);	/* Check we've released all buffer pins */	AtEOXact_Buffers(true);	/* Clean up the relation cache */	AtEOXact_RelationCache(true);	/* notify and flatfiles don't need a postprepare call */	PostPrepare_PgStat();	PostPrepare_Inval();	PostPrepare_smgr();	AtEOXact_MultiXact();	PostPrepare_Locks(xid);	ResourceOwnerRelease(TopTransactionResourceOwner,						 RESOURCE_RELEASE_LOCKS,						 true, true);	ResourceOwnerRelease(TopTransactionResourceOwner,						 RESOURCE_RELEASE_AFTER_LOCKS,						 true, true);	/* Check we've released all catcache entries */	AtEOXact_CatCache(true);	/* PREPARE acts the same as COMMIT as far as GUC is concerned */	AtEOXact_GUC(true, 1);	AtEOXact_SPI(true);	AtEOXact_xml();	AtEOXact_on_commit_actions(true);	AtEOXact_Namespace(true);	/* smgrcommit already done */	AtEOXact_Files();	AtEOXact_ComboCid();	AtEOXact_HashTables(true);	/* don't call AtEOXact_PgStat here */	CurrentResourceOwner = NULL;	ResourceOwnerDelete(TopTransactionResourceOwner);	s->curTransactionOwner = NULL;	CurTransactionResourceOwner = NULL;	TopTransactionResourceOwner = NULL;	AtCommit_Memory();	s->transactionId = InvalidTransactionId;	s->subTransactionId = InvalidSubTransactionId;	s->nestingLevel = 0;	s->gucNestLevel = 0;	s->childXids = NULL;	s->nChildXids = 0;	s->maxChildXids = 0;	/*	 * done with 1st phase commit processing, set current transaction state	 * back to default	 */	s->state = TRANS_DEFAULT;	RESUME_INTERRUPTS();}/* *	AbortTransaction */static voidAbortTransaction(void){	TransactionState s = CurrentTransactionState;	TransactionId latestXid;	/* Prevent cancel/die interrupt while cleaning up */	HOLD_INTERRUPTS();	/* Make sure we have a valid memory context and resource owner */	AtAbort_Memory();	AtAbort_ResourceOwner();	/*	 * Release any LW locks we might be holding as quickly as possible.	 * (Regular locks, however, must be held till we finish aborting.)	 * Releasing LW locks is critical since we might try to grab them again	 * while cleaning up!	 */	LWLockReleaseAll();	/* Clean up buffer I/O and buffer context locks, too */	AbortBufferIO();	UnlockBuffers();	/*	 * Also clean up any open wait for lock, since the lock manager will choke	 * if we try to wait for another lock before doing this.	 */	LockWaitCancel();	/*	 * check the current transaction state	 */	if (s->state != TRANS_INPROGRESS && s->state != TRANS_PREPARE)		elog(WARNING, "AbortTransaction while in %s state",			 TransStateAsString(s->state));	Assert(s->parent == NULL);	/*	 * set the current transaction state information appropriately during the	 * abort processing	 */	s->state = TRANS_ABORT;	/*	 * Reset user ID which might have been changed transiently.  We need this	 * to clean up in case control escaped out of a SECURITY DEFINER function	 * or other local change of CurrentUserId; therefore, the prior value	 * of SecurityDefinerContext also needs to be restored.	 *	 * (Note: it is not necessary to restore session authorization or role	 * settings here because those can only be changed via GUC, and GUC will	 * take care of rolling them back if need be.)	 */	SetUserIdAndContext(s->prevUser, s->prevSecDefCxt);	/*	 * do abort processing	 */	AfterTriggerEndXact(false);	AtAbort_Portals();	AtEOXact_LargeObject(false);	/* 'false' means it's abort */	AtAbort_Notify();	AtEOXact_UpdateFlatFiles(false);	/*	 * Advertise the fact that we aborted in pg_clog (assuming that we got as	 * far as assigning an XID to advertise).	 */	latestXid = RecordTransactionAbort(false);	PG_TRACE1(transaction__abort, MyProc->lxid);	/*	 * Let others know about no transaction in progress by me. Note that this	 * must be done _before_ releasing locks we hold and _after_	 * RecordTransactionAbort.	 */	ProcArrayEndTransaction(MyProc, latestXid);	/*	 * Post-abort cleanup.	See notes in CommitTransaction() concerning	 * ordering.	 */	CallXactCallbacks(XACT_EVENT_ABORT);	ResourceOwnerRelease(TopTransactionResourceOwner,						 RESOURCE_RELEASE_BEFORE_LOCKS,						 false, true);	AtEOXact_Buffers(false);	AtEOXact_RelationCache(false);	AtEOXact_Inval(false);	smgrDoPendingDeletes(false);	AtEOXact_MultiXact();	ResourceOwnerRelease(TopTransactionResourceOwner,						 RESOURCE_RELEASE_LOCKS,						 false, true);	ResourceOwnerRelease(TopTransactionResourceOwner,						 RESOURCE_RELEASE_AFTER_LOCKS,						 false, true);	AtEOXact_CatCache(false);	AtEOXact_GUC(false, 1);	AtEOXact_SPI(false);	AtEOXact_xml();	AtEOXact_on_commit_actions(false);	AtEOXact_Namespace(false);	smgrabort();	AtEOXact_Files();	AtEOXact_ComboCid();	AtEOXact_HashTables(false);	AtEOXact_PgStat(false);	pgstat_report_xact_timestamp(0);	/*	 * State remains TRANS_ABORT until CleanupTransaction().	 */	RESUME_INTERRUPTS();}/* *	CleanupTransaction */static voidCleanupTransaction(void){	TransactionState s = CurrentTransactionState;	/*	 * State should still be TRANS_ABORT from AbortTransaction().	 */	if (s->state != TRANS_ABORT)		elog(FATAL, "CleanupTransaction: unexpected state %s",			 TransStateAsString(s->state));	/*	 * do abort cleanup processing	 */	AtCleanup_Portals();		/* now safe to release portal memory */	CurrentResourceOwner = NULL;	/* and resource owner */	if (TopTransactionResourceOwner)		ResourceOwnerDelete(TopTransactionResourceOwner);	s->curTransactionOwner = NULL;	CurTransactionResourceOwner = NULL;	TopTransactionResourceOwner = NULL;	AtCleanup_Memory();			/* and transaction memory */	s->transactionId = InvalidTransactionId;	s->subTransactionId = InvalidSubTransactionId;	s->nestingLevel = 0;	s->gucNestLevel = 0;	s->childXids = NULL;	s->nChildXids = 0;	s->maxChildXids = 0;	/*	 * done with abort processing, set current transaction state back to	 * default	 */	s->state = TRANS_DEFAULT;}/* *	StartTransactionCommand */voidStartTransactionCommand(void){	TransactionState s = CurrentTransactionState;	switch (s->blockState)	{			/*			 * if we aren't in a transaction block, we just do our usual start			 * transaction.			 */		case TBLOCK_DEFAULT:			StartTransaction();			s->blockState = TBLOCK_STARTED;			break;			/*			 * We are somewhere in a transaction block or subtransaction and			 * about to start a new command.  For now we do nothing, but			 * someday we may do command-local resource initialization. (Note			 * that any needed CommandCounterIncrement was done by the			 * previous CommitTransactionCommand.)			 */		case TBLOCK_INPROGRESS:		case TBLOCK_SUBINPROGRESS:			break;			/*			 * Here we are in a failed transaction block (one of the commands			 * caused an abort) so we do nothing but remain in the abort			 * state.  Eventually we will get a ROLLBACK command which will			 * get us out of this state.  (It is up to other code to ensure			 * that no commands other than ROLLBACK will be processed in these			 * states.)			 */		case TBLOCK_ABORT:		case TBLOCK_SUBABORT:			break;			/* These cases are invalid. */		case TBLOCK_STARTED:		case TBLOCK_BEGIN:		case TBLOCK_SUBBEGIN:		case TBLOCK_END:		case TBLOCK_SUBEND:		case TBLOCK_ABORT_END:		case TBLOCK_SUBABORT_END:		case TBLOCK_ABORT_PENDING:		case TBLOCK_SUBABORT_PENDING:		case TBLOCK_SUBRESTART:		case TBLOCK_SUBABORT_RESTART:		case TBLOCK_PREPARE:			elog(ERROR, "StartTransactionCommand: unexpected state %s",				 BlockStateAsString(s->blockState));			break;	}	/*	 * We must switch to CurTransactionContext before returning. This is	 * already done if we called StartTransaction, otherwise not.	 */	Assert(CurTransactionContext != NULL);	MemoryContextSwitchTo(CurTransactionContext);}/* *	CommitTransactionCommand */voidCommitTransactionCommand(void){	TransactionState s = CurrentTransactionState;	switch (s->blockState)	{			/*			 * This shouldn't happen, because it means the previous			 * StartTransactionCommand didn't set the STARTED state			 * appropriately.			 */		case TBLOCK_DEFAULT:			elog(FATAL, "CommitTransactionCommand: unexpected state %s",				 BlockStateAsString(s->blockState));			break;			/*			 * If we aren't in a transaction block, just do our usual			 * transaction commit, and return to the idle state.			 */		case TBLOCK_STARTED:			CommitTransaction();			s->blockState = TBLOCK_DEFAULT;			break;			/*			 * We are completing a "BEGIN TRANSACTION" command, so we change			 * to the "transaction block in progress" state and return.  (We			 * assume the BEGIN did nothing to the database, so we need no			 * CommandCounterIncrement.)			 */		case TBLOCK_BEGIN:			s->blockState = TBLOCK_INPROGRESS;			break;			/*			 * This is the case when we have finished executing a command			 * someplace within a transaction block.  We increment the command			 * counter and return.			 */		case TBLOCK_INPROGRESS:		case TBLOCK_SUBINPROGRESS:			CommandCounterIncrement();			break;			/*			 * We are completing a "COMMIT" command.  Do it and return to the			 * idle state.			 */		case TBLOCK_END:			CommitTransaction();			s->blockState = TBLOCK_DEFAULT;			break;			/*			 * Here we are in the middle of a transaction block but one of the			 * commands caused an abort so we do nothing but remain in the			 * abort state.  Eventually we will get a ROLLBACK comand.			 */		case TBLOCK_ABORT:		case TBLOCK_SUBABORT:			break;			/*			 * Here we were in an aborted transaction block and we just got			 * the ROLLBACK command from the user, so clean up the			 * already-aborted transaction and return to the idle state.			 */		case TBLOCK_ABORT_END:			CleanupTransaction();			s->blockState = TBLOCK_DEFAULT;			break;			/*			 * Here we were in a perfectly good transaction block but the user			 * told us to ROLLBACK anyway.	We have to abort the transaction			 * and then clean up.			 */		case TBLOCK_ABORT_PENDING:			AbortTransaction();			CleanupTransaction();			s->blockState = TBLOCK_DEFAULT;			break;			/*			 * We are completing a "PREPARE TRANSACTION" command.  Do it and			 * return to the idle state.			 */		case TBLOCK_PREPARE:			PrepareTransaction();			s->blockState = TBLOCK_DEFAULT;			break;			/*			 * We were just issued a SAVEPOINT inside a transaction b

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -