Re: Functions and transactions

Поиск
Список
Период
Сортировка
От Kris Kiger
Тема Re: Functions and transactions
Дата
Msg-id 4230A6AA.6030204@musicrebellion.com
обсуждение исходный текст
Ответ на Re: Functions and transactions  (Tom Lane <tgl@sss.pgh.pa.us>)
Ответы Re: Functions and transactions  (Tom Lane <tgl@sss.pgh.pa.us>)
Список pgsql-admin
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
>
>


В списке pgsql-admin по дате отправления:

Предыдущее
От: Adrian Nida
Дата:
Сообщение: PostgreSQL pam ldap document
Следующее
От: Tom Lane
Дата:
Сообщение: Re: IO Timeout