Search code examples
c++exceptiontransactionsraii

Having a destructor take different actions depending on whether an exception occurred


I have some code to update a database table that looks like

try
{
   db.execute("BEGIN");
   // Lots of DELETE and INSERT     
   db.execute("COMMIT");
}
catch (DBException&)
{
   db.execute("ROLLBACK");
}

I'd like to wrap the transaction logic in an RAII class so I could just write

{
   DBTransaction trans(db);
   // Lots of DELETE and INSERT
}

but how would I write the destructor for it?


Solution

  • Use following:

    transaction tr(db);
    ...
    tr.commit();
    

    When tr.commit() completes it sets the state to "commit done" and destructor does nothing, otherwise it rollbacks.

    Checking for exception is bad idea, consider:

    transaction tr(db);
    ...
    if(something_wrong)
       return; // Not throw
    ...
    tr.commit();
    

    In this case you probably expect rather rollback then commit but commit would be done.

    Edit: but if you still want it badly, take a look on std::uncaught_exception() but read this first http://www.gotw.ca/gotw/047.htm