【问题标题】:Can a SELECT performed with READ COMMITTED trigger an exception in Postgresql?使用 READ COMMITTED 执行的 SELECT 可以在 Postgresql 中触发异常吗?
【发布时间】:2014-03-28 18:28:50
【问题描述】:

我需要拍摄一些表格行的快照 (SELECT) 以供显示。这些行将永远不会在同一个事务中被修改或删除,或传输到可以修改这些行的另一个事务。我只想在 Postgresql 函数中进行类似快照的简单读取。

例如:

SELECT * FROM "my_table" WHERE "amount" < 1000;

我正在考虑在我的 Postgresql 函数中设置 READ COMMITTED 事务级别:

SET TRANSACTION ISOLATION LEVEL READ COMMITTED;

这是否能确保我的 SELECT 永远不会遇到异常,无论其他繁重而复杂的事务是否同时运行?我相信是的,但我不是 Postgresql 专家。

更新:

在阅读更多内容后,我想知道这是否也可以解决问题?

SET TRANSACTION ISOLATION LEVEL READ ONLY DEFERRABLE

【问题讨论】:

  • 那将是REPEATABLE READ 而不是默认的READ COMMITTED,但这不能在函数中设置。为什么不根据查询打开CURSOR 并在完成后关闭它?
  • 一次检索所有行在我的情况下很好,所以我不需要游标。那么,您是说 SET TRANSACTION ISOLATION LEVEL REPEATED READ 吗?解决了我的问题?如果是,请创建一个解决方案,我会批准它!
  • 单个 SQL 语句与快照一起使用,因此如果您一次检索所有行,我认为开始时不会有问题。但是,如果您想更改隔离级别,则无法在函数内完成。如果你尝试它会出错。
  • 好的,那么如何更改函数内执行的事务的隔离级别?这可能吗?
  • 客户端,在调用函数之前。但是你真的很想阅读和消化文档中的SET TRANSACTION

标签: postgresql select read-committed-snapshot


【解决方案1】:

使用 Daniel 的信息,如果我执行以下操作来创建表格并填充它:

CREATE TABLE IF NOT EXISTS "my_table" (amount integer);
TRUNCATE "my_table";

INSERT INTO "my_table" VALUES (100);
INSERT INTO "my_table" VALUES (200);
INSERT INTO "my_table" VALUES (1000);
INSERT INTO "my_table" VALUES (2000);

CREATE OR REPLACE FUNCTION my_function()
    RETURNS SETOF "my_table" AS $$
BEGIN
    RETURN QUERY SELECT * FROM "my_table" WHERE "amount" < 1000;
END; $$
LANGUAGE plpgsql;

我可以在客户端设置一个事务级别,以检索我想要的具有我想要的隔离的行(尽管这对于简单的 SELECT 来说可能是多余的):

SET TRANSACTION ISOLATION LEVEL READ ONLY DEFERRABLE;
SELECT * FROM my_function();

【讨论】:

    猜你喜欢
    • 2012-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-29
    • 2013-12-05
    • 2015-03-24
    • 2014-05-09
    相关资源
    最近更新 更多