Re: Serialization, Locking...implement processing Queue with a table

From: "D(dot) Dante Lorenso" <dante(at)lorenso(dot)com>
To: "D(dot) Dante Lorenso" <dante(at)lorenso(dot)com>, "Manfred Koizar" <mkoi-pg(at)aon(dot)at>
Cc: "Tom Lane" <tgl(at)sss(dot)pgh(dot)pa(dot)us>, <pgsql-general(at)postgresql(dot)org>
Subject: Re: Serialization, Locking...implement processing Queue with a table
Date: 2003-05-14 09:36:35
Message-ID: 08d401c319fc$50114d30$1564a8c0@ROMULUS
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-general

> ---------- 8< -------------------- 8< ----------
> FUNCTION reserve_job
> BEGIN
> SELECT and LOCK row_id matching our criteria. (SELECT FOR UPDATE)
>
> IF (row_id was found) THEN
> RESERVE row_id (UPDATE)
> RETURN (row_id) -- done
> ELSE
> Ask "Are you Sure?" there are no rows matching our criteria?
> IF (certainly no row_id exists) THEN
> RETURN (0) -- no row ID exists
> ELSE
> RETURN reserve_job -- recursive call
> END IF
> END IF
> END
> I am going to try to implement your suggestion and see
> what I get in comparison to what I am seeing now with my
> LOCK/WAIT code.

Well, DAMNIT, this doesn't work. The problem goes back
to whatever the heck is happening inside the PL/PGSQL
function?!

The problem is that this function does not see the COMMITED
data from other functions. I've updated my code to the following:

---------- 8< -------------------- 8< -------------------- 8< ----------
CREATE OR REPLACE FUNCTION "public"."subs_get_next_queued" (bigint) RETURNS
bigint AS'
DECLARE
in_pid ALIAS FOR $1;
my_reserved_id BIGINT;
BEGIN
-- initialize the id
my_reserved_id := -1;

-- Find the ID we wish to reserve and get a lock on that row
SELECT subs_id INTO my_reserved_id
FROM subscription
WHERE subs_start_bill_date <= now()
AND subs_next_bill_date <= now()
AND subs_processor_id IS NULL
ORDER BY subs_id ASC
LIMIT 1
FOR UPDATE;

-- abort if there are no queued rows
IF NOT FOUND THEN
-- check again to see if there is something I need to process...
SELECT subs_id INTO my_reserved_id
FROM subscription
WHERE subs_start_bill_date <= now()
AND subs_next_bill_date <= now()
AND subs_processor_id IS NULL
ORDER BY subs_id ASC
LIMIT 1;

IF NOT FOUND THEN
RETURN (-1);
ELSE
RAISE NOTICE ''GOT LOCKED IN RACE [%]'', my_reserved_id;
SELECT subs_get_next_queued(in_pid) INTO my_reserved_id;
RETURN (my_reserved_id);
END IF;
END IF;

-- now go reserve the record with our processor id
UPDATE subscription SET
subs_processor_id = in_pid
WHERE subs_id = my_reserved_id;

-- this is the row we reserved...
RETURN (my_reserved_id);
END;
'LANGUAGE 'plpgsql' STABLE CALLED ON NULL INPUT SECURITY INVOKER;
---------- 8< -------------------- 8< -------------------- 8< ----------

Here is what is happening... Process one is started and is humming along
just fine. Then, I kick process 2 into gear and as soon as a collision
occurs, process 1 spins out of control and goes nuts in an infinite loop.
Apparently, it does not see the changes of process 2 even though they have
already been committed.

PROCESS 1 PROCESS 2
subs_get_next_queued
----------------------
126
(1 row)

subs_get_next_queued
----------------------
129
(1 row)

subs_get_next_queued
----------------------
140
(1 row)

NOTICE: GOT LOCKED IN RACE [140]
NOTICE: GOT LOCKED IN RACE [140]
NOTICE: GOT LOCKED IN RACE [140]
NOTICE: GOT LOCKED IN RACE [140]
NOTICE: GOT LOCKED IN RACE [140]
NOTICE: GOT LOCKED IN RACE [140]
NOTICE: GOT LOCKED IN RACE [140]
...
(continues forever and takes down
the PostgreSQL server. OUCH!)
subs_get_next_queued
----------------------
176
(1 row)

subs_get_next_queued
----------------------
182
(1 row)

(Continues until PostgreSQL dies
because of other processes
doings)

Can someone please explain what is happening to the PL/PGSQL function
in regards to commit visibility and transactions?

Dante

D. Dante Lorenso
dante(at)lorenso(dot)com
972-333-4139

Responses

Browse pgsql-general by date

  From Date Subject
Next Message Mirco Tamburini 2003-05-14 10:40:52 Heterogeneous service (like Oracle or Ms SQL Server)
Previous Message James Gregory 2003-05-14 08:58:24 server process segfaulting