首页 > 解决方案 > PostrgreSQL 尝试执行 plsh 函数

问题描述

注意: plsh是一种执行 shell 命令的 PostgreSQL 语言。

我正在尝试plsh从函数中调用plpgsql函数。

首先是更大的plpgsql功能:

CREATE OR REPLACE FUNCTION my_schema.big_function(my_arg character varying)
RETURNS text AS
$BODY$
BEGIN
    DROP TABLE IF EXISTS backend.table_B;
    CREATE TABLE backend.table_B AS
    --Create a table with a SELECT with some joins,
    --right now the resulting table is empty

    RAISE NOTICE 'table_B created';

    PERFORM my_schema.insert_from_shell(my_arg);

    RETURN 'Function Ended';
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;

然后是plsh函数:

CREATE OR REPLACE FUNCTION my_schema.insert_from_shell(my_arg character varying)
RETURNS text AS
$BODY$
#!/bin/sh
PGPASSWORD=mypassword psql -d mydatabase -h myhost -p myport -U myuser -c "INSERT INTO myschema.table_A(mycolumn) VALUES('$1')"
$BODY$
LANGUAGE plsh VOLATILE
COST 100;

当我尝试执行以下操作时:

SELECT my_schema.big_function('test');

永无止境。另一方面,如果我PERFORM从第一个函数中注释该行,并分别调用这两个函数,它们都会在不到一秒的时间内结束:

SELECT my_schema.big_function('test');
SELECT my_schema.insert_from_shell('test');

plsh从函数内部执行函数可能存在问题plpgsql,但我不确定。

我可以使用数据库外部的脚本分别调用这两个函数来解决它,但我宁愿从数据库内部解决它,并调用一个函数。

任何指针或帮助将不胜感激。

标签: postgresqldeadlock

解决方案


假设事务中的触发器在 上big_function放置了一个冲突的锁table_a,如评论中所建议的,您可以考虑以下解决方案:

使触发器 a CONSTRAINT TRIGGER(它必须是AFTER触发器)并将其声明为DEFERRABLE INITIALLY DEFERRED. 然后它不会在触发语句运行时正确运行,而是会延迟到COMMIT事务结束时。

到那时,insert_from_shell已经完成并提交,所以不会出现死锁。


推荐阅读