首页 > 解决方案 > postgresql libpqxx:多个查询作为一个事务

问题描述

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

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

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()可以从每个查询中读取行,我是否分别执行它们。

标签: postgresqllibpqlibpqxx

解决方案


如果您的目标是避免往返,则交易无济于事。

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

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


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

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

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


推荐阅读