次の機能に問題があります。この関数の目的は、60秒以内に呼び出された場合に再び返されることのないレコードのセットを返すことです(ほぼキューのように)。一時テーブルを使用した更新のPostgreSQLロック行
これを実行するとうまくいくようですが、スレッドアプリケーションで使用しているときに重複が表示されます。行を正しくロックしていますか?一時テーブルに挿入するときにFOR UPDATEを使用する正しい方法は何ですか?
CREATE OR REPLACE FUNCTION needs_quantities(computer TEXT)
RETURNS TABLE(id BIGINT, listing_id CHARACTER VARYING, asin CHARACTER VARYING, retry_count INT)
LANGUAGE plpgsql
AS $$
BEGIN
CREATE TEMP TABLE temp_needs_quantity ON COMMIT DROP
AS
SELECT
listing.id,
listing.listing_id,
listing.asin,
listing.retry_count
FROM listing
WHERE listing.id IN (
SELECT min(listing.id) AS id
FROM listing
WHERE (listing.quantity_assigned_to IS NULL
--quantity is null
-- and quantity assigned date is at least 60 seconds ago
-- and quantity date is within 2 hours
OR (
quantity IS NULL AND listing.quantity_assigned_date < now_utc() - INTERVAL '60 second'
AND (listing.quantity_date IS NULL OR listing.quantity_date > now_utc() - INTERVAL '2 hour')
)
)
AND listing.retry_count < 10
GROUP BY listing.asin
ORDER BY min(listing.retry_count), min(listing_date)
LIMIT 10
)
FOR UPDATE;
UPDATE listing
SET quantity_assigned_date = now_utc(), quantity_assigned_to = computer
WHERE listing.id IN (SELECT temp_needs_quantity.id
FROM temp_needs_quantity);
RETURN QUERY
SELECT *
FROM temp_needs_quantity
ORDER BY id;
END
$$