Re: Re: How to check whether the row was modified by this transaction before? - Mailing list pgsql-hackers

From Tom Lane
Subject Re: Re: How to check whether the row was modified by this transaction before?
Date
Msg-id 9921.1354829210@sss.pgh.pa.us
Whole thread Raw
In response to Re: How to check whether the row was modified by this transaction before?  (Andres Freund <andres@2ndquadrant.com>)
Responses Re: Re: How to check whether the row was modified by this transaction before?
List pgsql-hackers
Andres Freund <andres@2ndquadrant.com> writes:
> On 2012-12-06 13:59:32 -0500, Tom Lane wrote:
>> Andres Freund <andres@2ndquadrant.com> writes:
>>> On 2012-12-06 15:08:51 -0300, Alvaro Herrera wrote:
>>> Vlad Arkhipov <arhipov@dc.baikal.ru> writes:
>>>> In a BEFORE UPDATE trigger I need to know whether the row was previously
>>>> modified by this transaction. Is it safe to use xmin and txid_current()
>>>> for this purpose (xmin is 32-bit txid type but txid_current() returns
>>>> 64-bit bigint).

>>> I wonder if we shouldn't have a function txid_is_current(xid);

> I think architectures with an invalidation-queue to external caches (be
> it web-proxies or something lower-level) are quite popular. And with the
> new NOTIFY or pgq relatively simple. Ad to those its sensible not to
> post a single primary key more than once.

It strikes me that the notion of "this row was previously modified by
the current transaction" is squishier than it might look, and we'd do
well to clarify it before we consider exporting anything.  I think there
are three ways you might define such a function:

1. xmin is exactly equal to current (sub)transaction's XID.

2. xmin is this (sub)transaction's XID, or the XID of any subcommitted
subtransaction of it.

3. xmin is this (sub)transaction's XID, or the XID of any subcommitted
subtransaction, or the XID of any open parent transaction or
subcommitted subtransaction thereof.

If I've got my head screwed on straight, test #2 gives you the semantics
that "the previous row update cannot commit unless the action you are
about to take (with the current XID) commits".  Test #3 gives you the
semantics "the action you are about to take cannot commit unless the
previous row update does".  And test #1 doesn't have much to recommend
it except simplicity; while it might appear to have the semantics "the
previous row update will commit if and only if the action you are about
to take commits", it's actually narrower than that, because the same
could be said for already-subcommitted subtransactions.

In a cache invalidation context you probably want test #2, but
TransactionIdIsCurrentTransactionId() presently performs test #3.

(We discussed this point in connection with commit 7b90469b, and I've
been intending since then to take a closer look at all the callers of
TransactionIdIsCurrentTransactionId to see if these semantics are in
fact what they need.  We might have some bugs associated with confusion
on this.)

I'm not sure which of these semantics we might wish to expose to users.
        regards, tom lane



pgsql-hackers by date:

Previous
From: Asif Rehman
Date:
Subject: Re: why can't plpgsql return a row-expression?
Next
From: Alvaro Herrera
Date:
Subject: Re: [COMMITTERS] pgsql: Background worker processes