sql >> Base de Datos >  >> RDS >> PostgreSQL

pqxx reutilizar/reactivar una transacción de trabajo

pqxx::work es solo un pqxx::transaction<> que finalmente obtiene la mayor parte de su lógica de pqxx::transaction_base .

Esta clase no está destinada a servir para varias transacciones. En cambio, está destinado a una sola transacción dentro de un bloque de prueba/captura. Tiene una variable miembro de estado (m_Status ) que nunca se reinicia, incluso después de una confirmación.

El patrón normal es:

{
    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;
    }
}

Podría decirse que libpqxx podría revertir la transacción al eliminarla (para evitar por completo el intento/captura), pero no lo hace.

Parece que esto no se ajusta a su patrón de uso como desea G_work ser una variable global accesible desde varios lugares en su programa. Tenga en cuenta que pqxx::work no es la clase para los objetos de conexión, sino solo una forma de encapsular begin/commit/rollback con el manejo de excepciones de C++.

Sin embargo, libpqxx también le permite ejecutar declaraciones fuera de las transacciones (o al menos fuera de las transacciones administradas por libpqxx). Debe usar instancias de pqxx::nontransaction clase.

#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');");
}

Tenga en cuenta que esto es equivalente a:

#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');");
}

Eventualmente, nada le impide administrar las transacciones con pqxx::nontransaction . Esto es especialmente cierto si desea puntos de guardado . También recomendaría usar pqxx::nontransaction si su transacción está destinada a durar más allá del alcance de una función (por ejemplo, en el alcance global).

#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;");
}