【问题标题】:postgresql libpqxx: Several queries as one transactionpostgresql libpqxx:多个查询作为一个事务
【发布时间】:2020-02-10 08:23:39
【问题描述】:

在 postgresql 中插入/更新数据时,很容易在一个事务中execute multiple statements。 (我的目标是避免每个语句的服务器往返,尽管事务隔离通常很有用。)

查询时,我不清楚这是否可能。我不知何故需要知道什么函数将消耗每一位以及如何分离这些位。

connection c("dbname=test user=postgres hostaddr=127.0.0.1");
work w(c);
w.exec("SELECT a, b FROM my_table WHERE c = 3;");
w.exec("SELECT x, y, z FROM my_other_table WHERE c = 'dog';");
w.commit();

假设我有函数 my_parse_function()my_other_parse_function() 可以从每个查询中读取行,我是否分别执行它们。

【问题讨论】:

  • 您希望这两个查询在数据库的相同状态下执行吗?
  • 是的,抱歉:我有一个上下文,在开始计算之前我将连续执行几十个不同的 SELECT。问题是我是否可以在没有几十次往返数据库的情况下做到这一点。
  • 试试这个。 SET TRANSACTION SNAPSHOT 命令允许新事务使用与现有事务相同的快照运行。 postgresql.org/docs/12/sql-set-transaction.html

标签: postgresql libpq libpqxx


【解决方案1】:

如果您的目标是避免往返,那么事务将无济于事。

Postgres 中的事务隔离(与大多数 RDBMS 一样)不依赖于服务器一次执行所有语句。您事务中的每条语句都将在exec() 调用时发送并执行;隔离由引擎的concurrency control model 提供,允许多个客户端同时发出命令,并为每个客户端呈现不同的数据库状态视图。

如果有的话,在事务中包装一系列语句将增加更多通信开销,因为发出BEGINCOMMIT 命令需要额外的往返。


如果您想在一次往返中发出多个命令,您可以通过使用单个分号分隔的多语句字符串调用exec() 来实现。这些语句将被隐式视为单个事务,前提是没有显式事务已经处于活动状态,并且字符串不包含任何显式 BEGIN/COMMIT 命令。

如果您想发送多个查询protocol 确实允许返回多个结果集以响应多查询字符串,但exec() 不允许您访问给他们;它只是libpqPQexec()wrapper,它会丢弃除最后一个结果之外的所有结果。

相反,您可以使用pipeline,它允许您通过insert() 发出异步查询,然后在您闲暇时使用retrieve() 发出结果(如有必要,在它们到达之前一直阻塞)。设置retain() 限制将允许管道累积语句,然后将它们作为多命令字符串一起发送。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-11
    相关资源
    最近更新 更多