Re: Functions and transactions

From: Kris Kiger <kris(at)musicrebellion(dot)com>
To: "Pgsql-Admin (E-mail)" <pgsql-admin(at)postgresql(dot)org>
Subject: Re: Functions and transactions
Date: 2005-03-10 19:57:30
Message-ID: 4230A6AA.6030204@musicrebellion.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-admin pgsql-hackers pgsql-patches

In your second paragraph, I think that you are saying that SELECT FOR
UPDATE only locks one row, even though the select itself may return
many. Am I mis-interpreting you? Also, what do you mean by seizing on
a non-active row?

Your assumption about pkey_id is right, I meant for that to mean partial
key, bad naming on my part ;-).

In my case, the third paragraph applies to this situation, because I can
assume that there will always be an entry in the table that will be
active with that pkey_id (lets call this partialKey_id from now on, to
avoid further confusion).

The alternative you offer is a good idea, I didn't realize that I had
the option to create a unique index on a subset of data within the
table. Unfortunately, it will not work in this situation. I don't have
the option to report failure to the front-end application. I suppose,
i'm looking for a method to only allow one invocation of this function,
per partialKey_id, at a time.

If you have any other alternatives or suggestions, I'm all ears, err
eyes... Anyway, thank you ;-)

Kris

Tom Lane wrote:

>Mmm. This might work as you expect in 8.0, but it surely won't in any
>prior release, because before 8.0 we didn't advance the transaction
>snapshot between statements of a function.
>
>Another issue is that your SELECT FOR UPDATE locks only one of the
>rows having the target pkey_id (I assume that column is misnamed and
>isn't actually a primary key?). If it happened to seize on a non-active
>row then it might not accomplish your goal of blocking until other
>updaters of the same row set commit. That would allow the UPDATE to
>start and set its snapshot, which would mean you lose because it
>wouldn't see the newly inserted row from the other transaction.
>
>Even more to the point, if there aren't yet any committed rows at all of
>the target pkey_id, there is nothing for the SELECT FOR UPDATE to block
>on at all. You could fix the first problem in various ways but I see no
>way around this one. Unless you can guarantee that there will always be
>a suitable row already in existence, I think you have to abandon the
>idea of using a SELECT FOR UPDATE for locking.
>
>One possibility is to create a unique partial index:
>
>CREATE UNIQUE INDEX foo ON table1(pkey_id) WHERE active ;
>
>This will provide an enforcement that you don't have more than one
>active row at a time. Now you just simplify the trigger to
> update table1 set active = false where NEW.pkey_id = pkey_id and active;
> NEW.active := true;
>Race conditions will end up causing unique-key errors, which you can just
>retry.
>
> regards, tom lane
>
>

In response to

Responses

Browse pgsql-admin by date

  From Date Subject
Next Message Alex Turner 2005-03-10 21:44:53 Fwd: IO Timeout
Previous Message Adrian Nida 2005-03-10 19:36:52 PostgreSQL pam ldap document

Browse pgsql-hackers by date

  From Date Subject
Next Message johnnnnnn 2005-03-10 20:01:28 Re: [HACKERS] We are not following the spec for HAVING without GROUP BY
Previous Message Adrian Nida 2005-03-10 19:36:52 PostgreSQL pam ldap document

Browse pgsql-patches by date

  From Date Subject
Next Message Bruce Momjian 2005-03-10 21:19:33 Re: [pgsql-hackers-win32] [HACKERS] snprintf causes regression tests
Previous Message Nicolai Tufar 2005-03-10 19:22:13 Re: [pgsql-hackers-win32] snprintf causes regression tests to fail