X-Original-To: pgsql-sql@postgresql.org Received: from localhost (postgresql.org [64.49.215.8]) by postgresql.org (Postfix) with ESMTP id 8A7C0475458 for ; Wed, 19 Feb 2003 07:49:09 -0500 (EST) Received: from anchor-post-32.mail.demon.net (anchor-post-32.mail.demon.net [194.217.242.90]) by postgresql.org (Postfix) with ESMTP id AF3CD475425 for ; Wed, 19 Feb 2003 07:49:08 -0500 (EST) Received: from mwynhau.demon.co.uk ([193.237.186.96] helo=mainbox.archonet.com) by anchor-post-32.mail.demon.net with esmtp (Exim 3.35 #1) id 18lTeu-0004nT-0W; Wed, 19 Feb 2003 12:49:09 +0000 Received: from localhost (localhost.localdomain [127.0.0.1]) by mainbox.archonet.com (Postfix) with ESMTP id 0065F1736D; Wed, 19 Feb 2003 12:49:07 +0000 (GMT) Received: from client.archonet.com (client.archonet.com [192.168.1.16]) by mainbox.archonet.com (Postfix) with ESMTP id D7C42162AB; Wed, 19 Feb 2003 12:49:05 +0000 (GMT) Content-Type: text/plain; charset="iso-8859-1" From: Richard Huxton Organization: Archonet Ltd To: Dave Gomboc , Tambet Matiisen Subject: Re: select from update from select? Date: Wed, 19 Feb 2003 12:49:03 +0000 User-Agent: KMail/1.4.3 Cc: pgsql-sql@postgresql.org References: In-Reply-To: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Message-Id: <200302191249.04316.dev@archonet.com> X-Virus-Scanned: by AMaViS snapshot-20020531 X-Virus-Scanned: by AMaViS new-20020517 X-Archive-Number: 200302/423 X-Sequence-Number: 11821 On Tuesday 18 Feb 2003 8:57 am, Dave Gomboc wrote: > On Mon, 17 Feb 2003, Tambet Matiisen wrote: > > Why not just store the work_order_id in temporary variable? You need to > > do SELECT FOR UDPATE in this case, to avoid reserving the same work > > twice. > > This doesn't work -- for the reason you give: > > While testing this, I discovered, that it doesn't work exactly as I > > expected. Suppose one transaction locks row with work_queue_id =3D 1. N= ow > > before the first transactions has finished, second comes in and tries to > > get lock for the same row. SELECT FOR UPDATE in second transaction > > blocks as expected. But when first transaction finishes, the SELECT in > > second transaction returns 0 rows, not next row that satisfies the > > conditions. I'm not sure if this should be considered bug or feature. > > But you have to test if the query returned any rows anyway, because the > > same happens when there are no unreserved works in queue. > > It's definitely a bug to me. The purpose of the work_queue is hold the > pool of tasks to be done, and to allow different machines to indicate that > they will do a certain task without any master program to tell machines > what work to do. With the above process, concurrent attempts block > (except for one), then they don't even get a row! I definitely want > concurrent requests to not haggle over the same row, there'd be way too > much contention between machines, and it defeats the whole purpose of more > than one job being available simultaneously. If PostgreSQL had a SKIP > LOCKED feature, I'd be in business, but (AFAIK) it doesn't? Using NOWAIT > and doing a large number of retries using some random back-off scheme > seems like a big hack rather than something that would actually work > acceptably. This has come up before - check the archives for details. One solution is to have a "processed" flag with values: U - unprocessed X - executing D - done You claim a job by changing from U to X - this takes very little time, so y= our=20 worker processes can simply sit in a loop trying. When work is complete the= =20 flag is marked D. This has the added advantage that you can spot rows where processing starte= d=20 but didn't complete due to a crash etc. Another solution if you know how many workers you have is to have a manager= =20 process which tags each job with a worker ID, but this does tend to make th= e=20 manager a point of failure. --=20 Richard Huxton