Re: FOR SHARE vs FOR UPDATE locks

From: "Simon Riggs" <simon(at)2ndquadrant(dot)com>
To: "Tom Lane" <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: "Alvaro Herrera" <alvherre(at)alvh(dot)no-ip(dot)org>, <pgsql-hackers(at)postgreSQL(dot)org>
Subject: Re: FOR SHARE vs FOR UPDATE locks
Date: 2006-12-01 08:42:23
Message-ID: 1164962544.3778.847.camel@silverbirch.site
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-docs pgsql-hackers

On Thu, 2006-11-30 at 17:06 -0500, Tom Lane wrote:

> I just realized that we have a bit of a problem with upgrading row
> locks. Consider the following sequence:
>
> regression=# begin;
> BEGIN
> regression=# select * from int4_tbl where f1 = 0 for share;
> f1
> ----
> 0
> (1 row)
>
> regression=# savepoint x;
> SAVEPOINT
> regression=# select * from int4_tbl where f1 = 0 for update;
> f1
> ----
> 0
> (1 row)
>
> regression=# rollback to x;
> ROLLBACK
>
> The FOR UPDATE replaces the former shared row lock with an exclusive
> lock in the name of the subtransaction. After the ROLLBACK, the row
> appears not to be locked at all (it is ex-locked with XMAX = a failed
> transaction), so another backend could come along and modify it.
> That shouldn't happen --- we should act as though the outer
> transaction's FOR SHARE lock is still held.
>
> Unfortunately, I don't think there is any good way to implement that,
> since we surely don't have room in the tuple header to track multiple
> locks. One possibility is to try to assign the ex-lock in the name
> of the highest subtransaction holding a row lock, but that seems messy,
> and it wouldn't really have the correct semantics anyway --- in the
> above example, the outer transaction would be left holding ex-lock
> which would be surprising.

ISTM that multitrans could be used here. Two xids, one xmax.

Maybe the semantics of that use are slightly different from the normal
queueing mechanism, but it seems straightforward enough.

> I'm tempted to just error out in this scenario rather than allow the
> lock upgrade. Thoughts?

This close to release, I'll support you in choosing to just throw an
error. This should be fairly rare. Lock upgrades are deadlock prone
anyhow, so not a recommended coding practice and we would have a valid
practical reason for not allowing them (at this time).

It is something to fix later though: If I did need to do a lock upgrade,
I would code it with a savepoint so that deadlocks can be trapped and
retried.

IMHO the savepoint-related locking semantics aren't documented at all,
which is probably why such things have gone so long undetected.

--
Simon Riggs
EnterpriseDB http://www.enterprisedb.com

In response to

Responses

Browse pgsql-docs by date

  From Date Subject
Next Message Alvaro Herrera 2006-12-01 11:37:11 Re: FOR SHARE vs FOR UPDATE locks
Previous Message Tom Lane 2006-12-01 07:46:59 Re: FOR SHARE vs FOR UPDATE locks

Browse pgsql-hackers by date

  From Date Subject
Next Message Heikki Linnakangas 2006-12-01 09:42:49 Re: Storing session-local data
Previous Message Elijah Epifanov 2006-12-01 08:25:25 Storing session-local data