From: John Reeve <jreeve@pelagodesign.com>
To: Craig Ringer <craig@postnewspapers.com.au>
Cc: pgsql-sql@postgresql.org
Subject: Re: Sequential non unique IDs
Date: Sun, 6 Apr 2008 20:18:24 -0700
Message-ID: <E3BA5CEC8F665345BF4993E64A5F5C26C255E2@2exchange.pelagodesign.com> (raw)
In-Reply-To: <47F30A70.3090507@postnewspapers.com.au>
References: <E3BA5CEC8F665345BF4993E64A5F5C26C2556B@2exchange.pelagodesign.com>
<47F30A70.3090507@postnewspapers.com.au>
Thanks! I was able to resolve this by using SELECT FOR UPDATE on a table
row that both tasks had in common. In this case, the customer table.
Since only one transaction can lock the row at a time, the latter
transaction will be put on hold until the first one commits. This will
work perfectly.
Thanks again!
- John
-----Original Message-----
From: Craig Ringer [mailto:craig@postnewspapers.com.au]
Sent: Tuesday, April 01, 2008 9:24 PM
To: John Reeve
Cc: pgsql-sql@postgresql.org
Subject: Re: [SQL] Sequential non unique IDs
John Reeve wrote:
> I've already considered:
> 1. I can't lock the table, because there are too many inserts
> happening and it will slow down the app.
In a locking approach you may not need to lock the whole table. You
should only need to lock the entry for the customer being altered, eg:
BEGIN;
SELECT 1 FROM task WHERE customerid = 92 FOR UPDATE;
INSERT INTO task (id, customerid, localid) VALUES (nextval('task_id'),
92, (SELECT MAX(localid) + 1 FROM task WHERE customerid = 92));
If I'm not mistaken, that should ensure that for any given customer ID
there's only one transaction holding the locks on that customer.
It won't prevent SELECTs from reading the customer's records, but you
don't mind that so long as they're not using the customer's records to
determine the least free localid. That'll help reduce the hit on your
app's performance, too. If you do mind the , use SELECT ... FOR SHARE
and you'll wait on the FOR UPDATE lock if one is active (however, it
might prove hard to obtain a FOR UPDATE lock if there are lots of FOR
SHARE operations active).
I *think* that'll work, but you should of course test and investigate
before doing anything as crazy as taking my word for it.
> Anyone know a solution for this? This can't be the first time anyone
> has ever tried to do this. Thanks!
If I'm not mistaken about the similarity, you might want to search the
archives for the thread "Primary Key with serial". It might be
informative.
--
Craig Ringer
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: pgsql-sql@postgresql.org
Cc: jreeve@pelagodesign.com, craig@postnewspapers.com.au
Subject: Re: Sequential non unique IDs
In-Reply-To: <E3BA5CEC8F665345BF4993E64A5F5C26C255E2@2exchange.pelagodesign.com>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox