我想将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块中的单个事务。它具有一个状态成员变量(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/