PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

pqxx повторно използване/активиране на работна транзакция

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 може да отмени транзакцията при изтриване (за да избегне напълно опита/улавянето), но не го прави.

Изглежда, че това не отговаря на вашия модел на използване, тъй като искате G_work да бъде глобална променлива, достъпна от няколко места във вашата програма. Моля, обърнете внимание, че pqxx::work не е класът за обекти за връзка, а просто начин за капсулиране на start/commit/rollback с обработка на изключения в C++.

Независимо от това, 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 . Това е особено вярно, ако искате точки за запис . Бих посъветвал също да използвате 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;");
}



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Дефинираната от потребителя функция на PostgreSQL в диалект за хибернация хвърля изключение

  2. При каква мощност SQL Server превключва към сканиране на индекс (срещу търсене)

  3. PostgreSQL Transaction Isolation READ UNCOMMITTED

  4. Fabric и Sudo като друг потребител

  5. PostgreSQL:формат на интервала като минути