Re: Nested transactions: deferred triggers

From: Alvaro Herrera <alvherre(at)dcc(dot)uchile(dot)cl>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: Patches <pgsql-patches(at)postgresql(dot)org>
Subject: Re: Nested transactions: deferred triggers
Date: 2003-06-12 03:42:44
Message-ID: 20030612034244.GC4027@dcc.uchile.cl
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-patches

On Wed, Jun 11, 2003 at 10:33:07PM -0400, Tom Lane wrote:

> My thought would be that TransactionGetDeferredTriggers() ought to be
> called in one place that then passes the list pointer to the other
> subroutines. I haven't looked at the code in detail to see how this
> fits in ... but I don't like the notion of all these little functions
> independently fetching a pointer from some nontrivial function. That
> opens you up to interesting problems if different functions manage to
> fetch different results.

Well, I can see it getting into serious trouble if something weird
happens. However, I don't know a better way to do this. Code snippets
follow.

typedef struct TransactionSpecialData
{
void *deferredTriggers;
/* some other things... */
} TransactionSpecialData;

typedef struct TransactionStateData
{
TransactionId transactionIdData;
...
/* the usual, and the "Special pointer" : */
TransactionSpecial special;
} TransactionStateData;

The TransactionSpecial is initialized on StartSubTransaction, which is
analogous to StartTransaction but is, of course, only called when a
subtransaction starts. If there's inconsistency in the management of
this, I don't think we have much way out but elog(PANIC) and such. I
don't have checks in place for this though.

When the (sub)transaction starts, DeferredTriggersBeginXact() is called
which does the same as in the posted patch plus a call to
TransactionSetDeferredTriggerQueue(). After that, the routines in
backend/commands/trigger.c just call
TransactionGetDeferredTriggerQueue() to get the current queue for
processing.

This routine is defined simply as:
void *
TransactionGetDeferredTriggerQueue(void)
{
TransactionState s = CurrentTransactionState;
return s->special->deferredTriggers;
}

and the setter is just the trivial opposite.

If there's a better way to do this I'll gladly rewrite this code. I
think the complexity of the mechanism I have in place is very close to
the minimum. One possible idea is to have a global variable that is
changed at subtransaction start... however I think handling that is more
complicated because we need to append some things on subtrans commit but
forget them on subtrans abort, so it's not that trivial.

--
Alvaro Herrera (<alvherre[a]dcc.uchile.cl>)
"Investigación es lo que hago cuando no sé lo que estoy haciendo"
(Wernher von Braun)

In response to

Browse pgsql-patches by date

  From Date Subject
Next Message Bruce Momjian 2003-06-12 05:24:17 Re: ipv6 patch #3
Previous Message Rod Taylor 2003-06-12 03:36:47 Synopsis inconsistencies