pqxx::work
hanyalah sebuah pqxx::transaction<>
yang akhirnya mendapatkan sebagian besar logikanya dari pqxx::transaction_base
.
Kelas ini tidak dimaksudkan untuk melayani beberapa transaksi. Sebaliknya, ini dimaksudkan untuk satu transaksi dalam blok coba/tangkap. Ini memiliki variabel anggota negara (m_Status
) yang tidak pernah diinisialisasi ulang, bahkan setelah komit.
Pola normalnya adalah:
{
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;
}
}
Diperdebatkan, libpqxx dapat mengembalikan transaksi pada penghapusan (untuk menghindari try/catch sepenuhnya) tetapi tidak.
Tampaknya ini tidak sesuai dengan pola penggunaan Anda seperti yang Anda inginkan G_work
menjadi variabel global yang dapat diakses dari beberapa tempat di program Anda. Harap dicatat bahwa pqxx::work bukan kelas untuk objek koneksi, tetapi hanya cara untuk mengenkapsulasi begin/commit/rollback dengan penanganan pengecualian C++.
Namun demikian, libpqxx juga memungkinkan Anda untuk mengeksekusi pernyataan di luar transaksi (atau setidaknya di luar transaksi yang dikelola libpqxx). Anda harus menggunakan instance pqxx::nontransaction
kelas.
#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');");
}
Harap dicatat bahwa ini setara dengan:
#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');");
}
Akhirnya, tidak ada yang menghalangi Anda untuk mengelola transaksi dengan pqxx::nontransaction
. Ini terutama benar jika Anda ingin savepoints
. Saya juga menyarankan menggunakan pqxx::nontransaction
jika transaksi Anda dimaksudkan untuk berlangsung di luar cakupan fungsi (mis. pada cakupan 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;");
}