gpt4 book ai didi

c++ - pqxx 重用/重新激活工作事务

转载 作者:可可西里 更新时间:2023-11-01 17:39:09 26 4
gpt4 key购买 nike

我想将 pqxx::work 用于多个查询和 promise ,而 commit 函数阻止我再次使用它。这是一个简单的例子:

pqxx::connection G_connexion("dbname=basetest user=usertest password=1234");
pqxx::work G_work(G_connexion);

int main(int argc, char* argv[]) {
G_work.exec("insert into test.table1(nom) VALUES('foo');");
G_work.commit();//until here, no problem
G_work.exec("insert into test.table1(nom) VALUES('bar');"); //error, transaction already closed
G_work.commit();
}

当我尝试插入 'bar' 值时,在提交之后,我得到一个 pqxx::usage_error :Error executing query. Attempt to activate transaction<READ COMMITTED> which is already closed

如何避免在提交更改后关闭连接?我可以使用 G_work=pqxx::work(G_connexion) 或其他等价物来重置 G_work 吗?此外,一个错误的请求不应该导致整个进程崩溃,只是进程中的那个(G_work 在失败后仍然可用)。

我必须保留同一个变量 G_Work,因为它将是一个从程序中很多地方调用的全局变量。

最佳答案

pqxx::work只是一个pqxx::transaction<>它最终从 pqxx::transaction_base 中获取大部分逻辑.

此类不适用于多个事务。相反,它适用于 try/catch block 中的单个事务。它有一个状态成员变量 ( m_Status ),即使在提交之后也不会重新初始化。

正常模式是:

{
pqxx::work l_work(G_connexion);
try {
l_work.exec("insert into test.table1(nom) VALUES('foo');");
l_work.commit();
} catch (const exception& e) {
l_work.abort();
throw;
}
}

可以说,libpqxx 可以在删除时回滚事务(以完全避免 try/catch),但事实并非如此。

这似乎不符合您想要的使用模式G_work成为可从程序中多个位置访问的全局变量。请注意,pqxx::work 不是连接对象的类,而只是一种使用 C++ 异常处理封装 begin/commit/rollback 的方法。

不过,libpqxx 还允许您在事务外执行语句(或至少在 libpqxx 管理的事务外)。您应该使用 pqxx::nontransaction 的实例类。

#include "pqxx/nontransaction"

pqxx::connection G_connexion("dbname=basetest user=usertest password=1234");
pqxx::nontransaction G_work(G_connexion);

int f() {
G_work.exec("insert into test.table1(nom) VALUES('foo');");
G_work.exec("insert into test.table1(nom) VALUES('bar');");
}

请注意,这等同于:

#include "pqxx/nontransaction"

pqxx::connection G_connexion("dbname=basetest user=usertest password=1234");

int f() {
pqxx::nontransaction l_work(G_connexion);
l_work.exec("insert into test.table1(nom) VALUES('foo');");
l_work.exec("insert into test.table1(nom) VALUES('bar');");
}

最终,没有什么能阻止您管理交易 pqxx::nontransaction .如果你想要 savepoints 则尤其如此。 .我还建议使用 pqxx::nontransaction如果您的交易旨在持续超出功能范围(例如在全局范围内)。

#include "pqxx/nontransaction"

pqxx::connection G_connexion("dbname=basetest user=usertest password=1234");
pqxx::nontransaction G_work(G_connexion);

int f() {
G_work.exec("begin;");
G_work.exec("insert into test.table1(nom) VALUES('foo');");
G_work.exec("savepoint f_savepoint;");
// If the statement fails, rollback to checkpoint.
try {
G_work.exec("insert into test.table1(nom) VALUES('bar');");
} catch (const pqxx::sql_error& e) {
G_work.exec("rollback to savepoint f_savepoint;");
}
G_work.exec("commit;");
}

关于c++ - pqxx 重用/重新激活工作事务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26464056/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com