diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2004-07-01 00:52:04 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2004-07-01 00:52:04 +0000 |
commit | 573a71a5da70d6e2503c8f53e3b4f26b3b6d738d (patch) | |
tree | 070f677b0043631518f83ce84ff201bf8fda700f /src/backend/commands/async.c | |
parent | 4c9aa572fa2ee60e8ac557b866eccc7310df0a09 (diff) | |
download | postgresql-573a71a5da70d6e2503c8f53e3b4f26b3b6d738d.tar.gz postgresql-573a71a5da70d6e2503c8f53e3b4f26b3b6d738d.zip |
Nested transactions. There is still much left to do, especially on the
performance front, but with feature freeze upon us I think it's time to
drive a stake in the ground and say that this will be in 7.5.
Alvaro Herrera, with some help from Tom Lane.
Diffstat (limited to 'src/backend/commands/async.c')
-rw-r--r-- | src/backend/commands/async.c | 72 |
1 files changed, 66 insertions, 6 deletions
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index 847f73ff06a..8e53d6af7d7 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/async.c,v 1.112 2004/05/26 04:41:10 neilc Exp $ + * $PostgreSQL: pgsql/src/backend/commands/async.c,v 1.113 2004/07/01 00:50:10 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -97,11 +97,17 @@ * State for outbound notifies consists of a list of all relnames NOTIFYed * in the current transaction. We do not actually perform a NOTIFY until * and unless the transaction commits. pendingNotifies is NIL if no - * NOTIFYs have been done in the current transaction. The List nodes and - * referenced strings are all palloc'd in TopTransactionContext. + * NOTIFYs have been done in the current transaction. + * + * The list is kept in CurTransactionContext. In subtransactions, each + * subtransaction has its own list in its own CurTransactionContext, but + * successful subtransactions attach their lists to their parent's list. + * Failed subtransactions simply discard their lists. */ static List *pendingNotifies = NIL; +static List *upperPendingNotifies = NIL; /* list of upper-xact lists */ + /* * State for inbound notifies consists of two flags: one saying whether * the signal handler is currently allowed to call ProcessIncomingNotify @@ -155,11 +161,11 @@ Async_Notify(char *relname) { /* * The name list needs to live until end of transaction, so store - * it in the top transaction context. + * it in the transaction context. */ MemoryContext oldcontext; - oldcontext = MemoryContextSwitchTo(TopTransactionContext); + oldcontext = MemoryContextSwitchTo(CurTransactionContext); pendingNotifies = lcons(pstrdup(relname), pendingNotifies); @@ -607,6 +613,60 @@ AtAbort_Notify(void) } /* + * AtSubStart_Notify() --- Take care of subtransaction start. + * + * Push empty state for the new subtransaction. + */ +void +AtSubStart_Notify(void) +{ + MemoryContext old_cxt; + + /* Keep the list-of-lists in TopTransactionContext for simplicity */ + old_cxt = MemoryContextSwitchTo(TopTransactionContext); + + upperPendingNotifies = lcons(pendingNotifies, upperPendingNotifies); + + pendingNotifies = NIL; + + MemoryContextSwitchTo(old_cxt); +} + +/* + * AtSubCommit_Notify() --- Take care of subtransaction commit. + * + * Reassign all items in the pending notifies list to the parent transaction. + */ +void +AtSubCommit_Notify(void) +{ + List *parentPendingNotifies; + + parentPendingNotifies = (List *) linitial(upperPendingNotifies); + upperPendingNotifies = list_delete_first(upperPendingNotifies); + + /* + * We could try to eliminate duplicates here, but it seems not worthwhile. + */ + pendingNotifies = list_concat(parentPendingNotifies, pendingNotifies); +} + +/* + * AtSubAbort_Notify() --- Take care of subtransaction abort. + */ +void +AtSubAbort_Notify(void) +{ + /* + * All we have to do is pop the stack --- the notifies made in this + * subxact are no longer interesting, and the space will be freed when + * CurTransactionContext is recycled. + */ + pendingNotifies = (List *) linitial(upperPendingNotifies); + upperPendingNotifies = list_delete_first(upperPendingNotifies); +} + +/* *-------------------------------------------------------------- * NotifyInterruptHandler * @@ -951,7 +1011,7 @@ ClearPendingNotifies(void) /* * We used to have to explicitly deallocate the list members and * nodes, because they were malloc'd. Now, since we know they are - * palloc'd in TopTransactionContext, we need not do that --- they'll + * palloc'd in CurTransactionContext, we need not do that --- they'll * go away automatically at transaction exit. We need only reset the * list head pointer. */ |