Re: Basic locking question

From: Michael Fuhr <mike(at)fuhr(dot)org>
To: Ben <bench(at)silentmedia(dot)com>
Cc: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>, "Joshua D(dot) Drake" <jd(at)commandprompt(dot)com>, pgsql-general(at)postgresql(dot)org
Subject: Re: Basic locking question
Date: 2005-09-06 23:51:32
Message-ID: 20050906235132.GA8350@winnie.fuhr.org
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-general

On Tue, Sep 06, 2005 at 04:25:38PM -0700, Ben wrote:
> So I'm looking for "lock <tablename> in exclusive mode"?

What version of PostgreSQL are you using? In 8.0 and later a
PL/pgSQL function could trap a unique constraint violation and issue
a SELECT query instead. If that sounds ugly then I'd say locking
the entire table is even uglier.

Here's a possible solution (only minimally tested):

CREATE FUNCTION getkey(k text) RETURNS integer AS $$
DECLARE
retval integer;
BEGIN
LOOP
SELECT INTO retval id FROM foo WHERE keyval = k;

EXIT WHEN FOUND;

BEGIN
INSERT INTO foo (keyval) VALUES (k);
RETURN currval(pg_get_serial_sequence('foo', 'id'));
EXCEPTION
WHEN UNIQUE_VIOLATION THEN
NULL;
END;
END LOOP;

RETURN retval;
END;
$$ LANGUAGE plpgsql VOLATILE STRICT;

This function should handle race conditions, and it should only
block when multiple transactions try to insert the same key. If
the key already exists then the expensive exception-handling code
won't be entered. Alternatively, you could try the INSERT first
and then do the SELECT if the INSERT failed.

--
Michael Fuhr

In response to

Browse pgsql-general by date

  From Date Subject
Next Message Alvaro Herrera 2005-09-07 02:48:38 Re: fix pg_autovacuum
Previous Message Scott Marlowe 2005-09-06 23:48:12 Re: SLOOOOOOOW