數據庫包含一個用戶表。只要用戶名是發送到數據庫的數據的一部分(即:通過函數),用戶就會被添加到表中,並且表中的用戶名應該是唯一的。在任何給定的函數調用中,單個用戶名也可能出現多次。穩定函數調用volatile函數:併發性問題
對於每個用戶名,我想獲得其現有ID或插入到用戶表中並返回ID。
我想到的解決方案是一個STABLE函數,它首先嚐試從users表中進行選擇,如果失敗,它會調用試圖插入用戶表的VOLATILE幫助函數。我更喜歡STABLE,因爲該函數的結果對於其餘事務是相同的,所以我希望在多次包含用戶名的情況下或者將它傳遞給其他函數尋找它的ID。
我的問題是:我的初始函數中的STABLE是否意味着併發插入(導致助手函數中的異常)永遠不會被初始函數看到,從而導致無限循環?
我已經包含了下面的定義。
CREATE SCHEMA orgnztn;
CREATE TABLE orgnztn.tUsers (
id serial NOT NULL,
usrid text NOT NULL,
PRIMARY KEY (id),
UNIQUE (usrid)
);
CREATE OR REPLACE FUNCTION orgnztn.getUserID (
IN p_usrid text
)
RETURNS integer
LANGUAGE plpgsql
STABLE
CALLED ON NULL INPUT
SECURITY INVOKER
AS $$
DECLARE
p_id integer;
BEGIN
IF p_usrid IS NULL THEN
RETURN NULL;
END IF;
p_usrid = upper(p_usrid);
LOOP
SELECT id INTO p_id
FROM orgnztn.tUsers
WHERE usrid = p_usrid
FETCH FIRST 1 ROWS ONLY;
IF found THEN
RETURN p_id;
END IF;
BEGIN
RETURN orgnztn.getUserID_helper(p_usrid);
EXCEPTION WHEN unique_violation THEN
-- loop
END;
END LOOP;
END;
$$;
CREATE OR REPLACE FUNCTION orgnztn.getUserID_helper (
IN p_usrid text
)
RETURNS integer
LANGUAGE plpgsql
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
AS $$
DECLARE
p_id integer;
BEGIN
INSERT INTO orgnztn.tUsers (usrid)
VALUES (p_usrid)
RETURNING id INTO p_id;
RETURN p_id;
END;
$$;