sql >> Databasteknik >  >> RDS >> PostgreSQL

pqxx återanvänd / återaktivera en arbetstransaktion

pqxx::work är bara en pqxx::transaction<> som så småningom får det mesta av sin logik från pqxx::transaction_base .

Denna klass är inte avsedd att användas för flera transaktioner. Istället är den avsedd för en enda transaktion inom ett försök/fångst-block. Den har en statmedlemsvariabel (m_Status ) som aldrig återinitieras, inte ens efter en commit.

Det normala mönstret är:

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

Förmodligen skulle libpqxx kunna återställa transaktionen vid radering (för att undvika försök/fånga helt) men det gör det inte.

Det verkar som att detta inte passar ditt användningsmönster som du vill ha G_work att vara en global variabel tillgänglig från flera ställen i ditt program. Observera att pqxx::work inte är klassen för anslutningsobjekt, utan bara ett sätt att kapsla in start/commit/rollback med C++ undantagshantering.

Ändå tillåter libpqxx dig också att utföra uttalanden utanför transaktioner (eller åtminstone utanför libpqxx-hanterade transaktioner). Du bör använda instanser av pqxx::nontransaction klass.

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

Observera att detta motsvarar:

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

Så småningom, inget hindrar dig från att hantera transaktioner med pqxx::nontransaction . Detta gäller särskilt om du vill ha savepoints . Jag rekommenderar också att du använder pqxx::nontransaction om din transaktion är avsedd att pågå utanför ett funktionsomfång (t.ex. globalt).

#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. Skriv till JSON-fil med CodeIgniter

  2. Kolumn finns inte i IN-satsen, men SQL körs

  3. Hur visar man det totala antalet för den sista raden efter filstatus?

  4. PostgreSQL:Hitta meningar närmast en given mening