ale*_*xis 8 c++ postgresql libpqxx
我想使用pqxx :: work进行多次查询和承诺,而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();
}
Run Code Online (Sandbox Code Playgroud)
当我尝试插入'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,因为它将是一个从程序中的许多地方调用的全局变量.
Pau*_*yot 10
pqxx::work只是pqxx::transaction<>最终得到其大部分逻辑的东西pqxx::transaction_base.
此类不适用于多个事务.相反,它适用于try/catch块中的单个事务.它有一个state成员variable(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;
}
}
Run Code Online (Sandbox Code Playgroud)
可以说,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');");
}
Run Code Online (Sandbox Code Playgroud)
请注意,这相当于:
#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');");
}
Run Code Online (Sandbox Code Playgroud)
最终,没有什么能够阻止你来管理事务与pqxx::nontransaction.如果您想要保存点,尤其如此.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;");
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5420 次 |
| 最近记录: |