Received: from localhost (unknown [200.46.204.184]) by developer.postgresql.org (Postfix) with ESMTP id 9F23F2E002E for ; Mon, 7 Apr 2008 00:19:31 -0300 (ADT) Received: from developer.postgresql.org ([200.46.204.71]) by localhost (mx1.hub.org [200.46.204.184]) (amavisd-maia, port 10024) with ESMTP id 50113-02 for ; Mon, 7 Apr 2008 00:19:26 -0300 (ADT) X-Greylist: from auto-whitelisted by SQLgrey-1.7.5 Received: from mx.myintervals.com (mx.myintervals.com [209.85.90.111]) by developer.postgresql.org (Postfix) with ESMTP id CE0B52E0038 for ; Mon, 7 Apr 2008 00:19:26 -0300 (ADT) Received: from mx.myintervals.com (localhost [127.0.0.1]) by mx.myintervals.com (Postfix) with ESMTP id 143271F6C6E2; Sun, 6 Apr 2008 20:19:25 -0700 (PDT) DomainKey-Signature: a=rsa-sha1; h=Received:X-MimeOLE:Content-class:MIME-Version:Content-Type:Content-Transfer-Encoding:Subject:Date:Message-ID:In-reply-to:X-MS-Has-Attach:X-MS-TNEF-Correlator:Thread-Topic:Thread-Index:References:From:To:Cc; b=HoOSw/N6k4dHG465mb6KO82924Oo2zm5rTUypPxw/B3Bf27ruPomdVsEeuE/b5+BVUdD7/NARTiaDDHUWapRlg==; c=nofws; d=pelagodesign.com; q=dns; s=mx Received: from 2exchange.pelagodesign.com (wsip-72-215-162-97.sb.sd.cox.net [72.215.162.97]) by mx.myintervals.com (Postfix) with ESMTP id E25781F6C6DE; Sun, 6 Apr 2008 20:19:24 -0700 (PDT) X-MimeOLE: Produced By Microsoft Exchange V6.5 Content-class: urn:content-classes:message MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Subject: Re: Sequential non unique IDs Date: Sun, 6 Apr 2008 20:18:24 -0700 Message-ID: In-reply-to: <47F30A70.3090507@postnewspapers.com.au> X-MS-Has-Attach: X-MS-TNEF-Correlator: Thread-Topic: [SQL] Sequential non unique IDs Thread-Index: AciUcRJtB7z2HiqfSVqNCSNP8hFfQAD7MfAg References: <47F30A70.3090507@postnewspapers.com.au> From: "John Reeve" To: "Craig Ringer" Cc: X-Virus-Scanned: Maia Mailguard 1.0.1 X-Spam-Status: No, hits=0.001 tagged_above=0 required=5 tests=AWL=0.001 X-Spam-Level: X-Archive-Number: 200804/32 X-Sequence-Number: 30571 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]=20 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=20 > 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 =3D 92 FOR UPDATE; INSERT INTO task (id, customerid, localid) VALUES (nextval('task_id'), 92, (SELECT MAX(localid) + 1 FROM task WHERE customerid =3D 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=20 > 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