DO $$
BEGIN
raise notice '%', (SELECT * from public.clientcalledthisfunction(1,2));
END $$;
CREATE OR REPLACE FUNCTION public.clientcalledthisfunction(userid1_ integer, userid2_ integer)
RETURNS integer
AS $$
DECLARE
result integer;
BEGIN
result:=(SELECT * from public.call_updatedata(userid1_, userid2_)) ;
RETURN result;
EXCEPTION WHEN others THEN
End $$ LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION public.call_updatedata(userid1_ integer, userid2_ integer)
RETURNS integer
AS $$
DECLARE
userdata_1 integer;
userdata_2 integer;
userdata_total integer;
BEGIN
SELECT * FROM public.updatedata(userid1_) INTO userdata_1;
SELECT * FROM public.updatedata(userid2_) INTO userdata_2;
userdata_total:=(userdata_1 + userdata_2);
RETURN userdata_total;
EXCEPTION WHEN others THEN
End $$ LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION public.updatedata(userid_ integer)
RETURNS integer
AS $$
DECLARE
userdata_ integer;
BEGIN
LOOP
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
BEGIN
SAVEPOINT foo;
SELECT userdata FROM public.footable WHERE userid=userid_ INTO userdata_;
UPDATE public.footable SET userdata = userdata_ + 1 WHERE userid=userid_ ;
EXIT ;
EXCEPTION WHEN others THEN
ROLLBACK TO SAVEPOINT foo;
END;
END LOOP;
RETURN userdata_ + 1;
EXCEPTION WHEN others THEN
END $$ language plpgsql;
Клиент calls public.clientcalledthisfunction()
функция;УРОВЕНЬ ИЗОЛЯЦИИ SERIALIZABLE lock postgresql 9.6
Мне нужно реализовать ISOLATION LEVEL SERIALIZABLE
на SELECT + UPDATE
в updatedata()
функции, потому что я не хочу «потерянное обновление» ... Я хочу, чтобы установить уровень изоляции SERIALIZABLE в public.updatedata function()
только.
И в updatedata()
функция, если есть исключение; я хочу, чтобы откатить к savepoint foo
и повторите select + update
процесс через петлю снова ...
Но я получаю error
говоря "control reached end of function without RETURN"
... Я не могу понять, где проблема.
.... «Но это на самом деле не работает, если вы используете сериализованную изоляцию, поскольку некоторые сбои сериализации могут быть найдены только в момент фиксации». ..... Нет другого способа сделать это? Я имею в виду работу вокруг? – sommeguyy
@sommeguyy Вы не ясно объяснили основную проблему, которую пытаетесь решить, поэтому трудно сказать. –
В итоге я решил свою проблему, используя блокировку «FOR UPDATE». – sommeguyy