void MDBRWTransactionImpl::commit()
{
closeRORWCursors();
- if (!d_txn) {
- return;
- }
-
- if(int retCode = mdb_txn_commit(d_txn); retCode != 0) {
- throw std::runtime_error("committing: " + MDBError(retCode));
+ if (d_txn != nullptr) {
+ int retCode = mdb_txn_commit(d_txn);
+ // Upon failure, mdb_txn_commit() performs an mdb_txn_abort() call,
+ // so we need to consider the transaction aborted and correctly
+ // deallocated.
+ d_txn = nullptr;
+ environment().decRWTX();
+ if (retCode != 0) {
+ throw std::runtime_error("committing: " + MDBError(retCode));
+ }
}
- environment().decRWTX();
- d_txn = nullptr;
}
void MDBRWTransactionImpl::abort()
{
closeRORWCursors();
- if (!d_txn) {
- return;
+ if (d_txn != nullptr) {
+ mdb_txn_abort(d_txn);
+ d_txn = nullptr;
+ // prevent the RO destructor from cleaning up the transaction itself
+ environment().decRWTX();
}
-
- mdb_txn_abort(d_txn);
- // prevent the RO destructor from cleaning up the transaction itself
- environment().decRWTX();
- d_txn = nullptr;
}
MDBROTransactionImpl::MDBROTransactionImpl(MDBEnv *parent, MDB_txn *txn):
{
closeROCursors();
// if d_txn is non-nullptr here, either the transaction object was invalidated earlier (e.g. by moving from it), or it is an RW transaction which has already cleaned up the d_txn pointer (with an abort).
- if (d_txn) {
+ if (d_txn != nullptr) {
mdb_txn_abort(d_txn); // this appears to work better than abort for r/o database opening
d_txn = nullptr;
}
{
closeROCursors();
// if d_txn is non-nullptr here, either the transaction object was invalidated earlier (e.g. by moving from it), or it is an RW transaction which has already cleaned up the d_txn pointer (with an abort).
- if (d_txn) {
+ if (d_txn != nullptr) {
mdb_txn_commit(d_txn); // this appears to work better than abort for r/o database opening
d_txn = nullptr;
}