设置postgresql存储过程的隔离级别
希望是一个简单的问题,但是我并不容易找到一个体面的答案。我可靠地通知PostgreSQL(特别是版本9.0.4)中的存储过程(用户定义的DB函数)本质上是事务性的,因为它们通过本身是一个事务的SELECT语句来调用。那么如何选择存储过程的隔离级别?我相信其他DBMS,所需的事务块将被封装在START TRANSACTION块中,所需的隔离级别是可选参数。
作为一个具体的组成例子,我想这样做: CREATE FUNCTION add_new_row(rowtext TEXT) RETURNS VOID AS $$ BEGIN INSERT INTO data_table VALUES (rowtext); UPDATE row_counts_table SET count=count+1; END; $$ LANGUAGE plpgsql SECURITY DEFINER; 并想象我想确保这个函数总是作为可序列化的事务执行(是的,是的,PostgreSQL SERIALIZABLE是不正确的可序列化,但这不是重点)。我不想要它被称为 START TRANSACTION ISOLATION LEVEL SERIALIZABLE; SELECT add_new_row('foo'); COMMIT; 那么如何将所需的隔离级别推到功能中呢?我相信我不能把隔离级别放在BEGIN语句中,如the manual says
对我来说最明显的做法是在函数定义中的某个地方使用SET TRANSACTION,例如: CREATE FUNCTION add_new_row(rowtext TEXT) RETURNS VOID AS $$ BEGIN SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; INSERT INTO data_table VALUES (rowtext); UPDATE row_counts_table SET count=count+1; END; $$ LANGUAGE plpgsql SECURITY DEFINER; 虽然这将被接受,但我不清楚,我可以依靠这个工作。 SET TRANSACTION的documentation说
这让我感到困惑,因为如果我调用一个孤立的SELECT add_new_row(‘foo’);语句我希望(假设我没有禁用自动提交)SELECT作为具有会话默认隔离级别的单行事务运行。 manual还说:
那么如果从具有较低隔离级别的事务中调用该函数会发生什么,例如: START TRANSACTION ISOLATION LEVEL READ COMMITTED; UPDATE row_counts_table SET count=0; SELECT add_new_row('foo'); COMMIT; 对于一个奖金问题:该功能的语言有什么区别吗?将PL / pgSQL中的隔离级别设置为与纯SQL不同? 我是标准和记录的最佳实践的粉丝,所以任何体面的参考将不胜感激。
你不能这样做
你可以做的是让你的功能检查当前的事务隔离级别是什么,如果不是你想要的事情,中止它。您可以通过运行SELECT current_setting(‘transaction_isolation’)然后检查结果来执行此操作。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |