PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

ponowne użycie pqxx / reaktywacja transakcji roboczej

pqxx::work to tylko pqxx::transaction<> który ostatecznie uzyskuje większość swojej logiki z pqxx::transaction_base .

Ta klasa nie jest przeznaczona do obsługi kilku transakcji. Zamiast tego jest przeznaczony do pojedynczej transakcji w bloku try/catch. Ma zmienną składową stanu (m_Status ), który nigdy nie jest ponownie inicjowany, nawet po zatwierdzeniu.

Normalny wzór to:

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

Prawdopodobnie libpqxx może cofnąć transakcję po usunięciu (aby całkowicie uniknąć próby/złapania), ale tak się nie dzieje.

Wygląda na to, że nie pasuje to do twojego wzorca użytkowania, jak chcesz G_work być zmienną globalną dostępną z kilku miejsc w twoim programie. Proszę zauważyć, że pqxx::work nie jest klasą dla obiektów połączeń, a jedynie sposobem na enkapsulację begin/commit/rollback z obsługą wyjątków C++.

Niemniej jednak libpqxx pozwala również na wykonywanie instrukcji poza transakcjami (lub przynajmniej poza transakcjami zarządzanymi przez libpqxx). Powinieneś użyć instancji pqxx::nontransaction klasa.

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

Pamiętaj, że jest to równoznaczne z:

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

Ostatecznie nic nie stoi na przeszkodzie w zarządzaniu transakcjami z pqxx::nontransaction . Jest to szczególnie ważne, jeśli chcesz punkty zapisu . Radziłbym również użyć pqxx::nontransaction jeśli Twoja transakcja ma trwać poza zakresem funkcji (np. w zakresie globalnym).

#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. alternatywa sp_send_dbmail w postgresie? Łatwy sposób na wysyłanie raportów e-mail Postgres?

  2. Jak działa POSITION() w PostgreSQL

  3. „uwierzytelnianie hasła nie powiodło się dla postgres użytkownika”

  4. Funkcja tworzenia PostgreSQL

  5. Grupuj według skróconej daty w JPA