summaryrefslogtreecommitdiff
path: root/src/backend/access/transam/xact.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/access/transam/xact.c')
-rw-r--r--src/backend/access/transam/xact.c60
1 files changed, 32 insertions, 28 deletions
diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c
index a0170b42e2..4b407015df 100644
--- a/src/backend/access/transam/xact.c
+++ b/src/backend/access/transam/xact.c
@@ -1753,12 +1753,10 @@ CommitTransaction(void)
Assert(s->parent == NULL);
/*
- * Do pre-commit processing (most of this stuff requires database access,
- * and in fact could still cause an error...)
- *
- * It is possible for CommitHoldablePortals to invoke functions that queue
- * deferred triggers, and it's also possible that triggers create holdable
- * cursors. So we have to loop until there's nothing left to do.
+ * Do pre-commit processing that involves calling user-defined code, such
+ * as triggers. Since closing cursors could queue trigger actions,
+ * triggers could open cursors, etc, we have to keep looping until there's
+ * nothing left to do.
*/
for (;;)
{
@@ -1768,19 +1766,23 @@ CommitTransaction(void)
AfterTriggerFireDeferred();
/*
- * Convert any open holdable cursors into static portals. If there
- * weren't any, we are done ... otherwise loop back to check if they
- * queued deferred triggers. Lather, rinse, repeat.
+ * Close open portals (converting holdable ones into static portals).
+ * If there weren't any, we are done ... otherwise loop back to check
+ * if they queued deferred triggers. Lather, rinse, repeat.
*/
- if (!CommitHoldablePortals())
+ if (!PreCommit_Portals(false))
break;
}
- /* Now we can shut down the deferred-trigger manager */
- AfterTriggerEndXact(true);
+ /*
+ * The remaining actions cannot call any user-defined code, so it's
+ * safe to start shutting down within-transaction services. But note
+ * that most of this stuff could still throw an error, which would
+ * switch us into the transaction-abort path.
+ */
- /* Close any open regular cursors */
- AtCommit_Portals();
+ /* Shut down the deferred-trigger manager */
+ AfterTriggerEndXact(true);
/*
* Let ON COMMIT management do its thing (must happen after closing
@@ -1954,12 +1956,10 @@ PrepareTransaction(void)
Assert(s->parent == NULL);
/*
- * Do pre-commit processing (most of this stuff requires database access,
- * and in fact could still cause an error...)
- *
- * It is possible for PrepareHoldablePortals to invoke functions that
- * queue deferred triggers, and it's also possible that triggers create
- * holdable cursors. So we have to loop until there's nothing left to do.
+ * Do pre-commit processing that involves calling user-defined code, such
+ * as triggers. Since closing cursors could queue trigger actions,
+ * triggers could open cursors, etc, we have to keep looping until there's
+ * nothing left to do.
*/
for (;;)
{
@@ -1969,19 +1969,23 @@ PrepareTransaction(void)
AfterTriggerFireDeferred();
/*
- * Convert any open holdable cursors into static portals. If there
- * weren't any, we are done ... otherwise loop back to check if they
- * queued deferred triggers. Lather, rinse, repeat.
+ * Close open portals (converting holdable ones into static portals).
+ * If there weren't any, we are done ... otherwise loop back to check
+ * if they queued deferred triggers. Lather, rinse, repeat.
*/
- if (!PrepareHoldablePortals())
+ if (!PreCommit_Portals(true))
break;
}
- /* Now we can shut down the deferred-trigger manager */
- AfterTriggerEndXact(true);
+ /*
+ * The remaining actions cannot call any user-defined code, so it's
+ * safe to start shutting down within-transaction services. But note
+ * that most of this stuff could still throw an error, which would
+ * switch us into the transaction-abort path.
+ */
- /* Close any open regular cursors */
- AtCommit_Portals();
+ /* Shut down the deferred-trigger manager */
+ AfterTriggerEndXact(true);
/*
* Let ON COMMIT management do its thing (must happen after closing