我有一个postgres函数,我想在循环中处理异常并继续。然而,这对于正常情况下工作正常。在扩展和测试时,它最终会陷入死锁。我假设这是因为www.example.com内部有多个事务function.is没有多个begin-end的方法可以解决这个问题。
CREATE OR REPLACE FUNCTION get_or_create_abc
input_dict json)
RETURNS TABLE(success_list text[], failed_list text[])
LANGUAGE 'plpgsql'
AS $BODY$
DECLARE
....
BEGIN
FOR key, value IN SELECT * FROM json_each(input_dict)
LOOP
FOR row IN SELECT json_array_elements(value)
LOOP
BEGIN
a := row->>0;
x := row->>1;
y := row->>2;
z := row->>3;
counter = 0 ;
WHILE counter < 3 LOOP
BEGIN
// functions//
EXIT;
EXCEPTION
WHEN UNIQUE_VIOLATION THEN
GET STACKED DIAGNOSTICS constraint_name_ := CONSTRAINT_NAME;
IF constraint_name_ = abc THEN
//..//
ELSIF constraint_name_ = cde THEN
//..//
exit;
ELSE
RAISE;
END IF;
END;
END LOOP;
END;
end loop;
END LOOP;
//...//
RETURN query select success_list,failed_list;
EXCEPTION
WHEN OTHERS THEN
//...//
END;
$BODY$;
ALTER FUNCTION protecto_vault.get_or_create_tokens(json)
OWNER TO test_user;
1条答案
按热度按时间vfhzx4xs1#
看起来有可能重写它,这样你就不需要一个循环了。循环可能会很慢,我猜如果你的update/insert在几个语句中运行,它会更快,这可能会防止死锁。
我建议将您的数据批处理到可以同时处理的逻辑组中,类似于此。
如果在这样的更新过程中仍然存在命中约束的问题,那么可以考虑将约束检查推迟到事务结束时进行。
例如
请注意,这仅在将约束创建为可延迟时有效。例如
请参阅Postgresql手册了解有关可延期约束的更多信息。