Alex Rivera | Logout

C++ Transaction-like Pattern for All or Nothing Work

Asked 2012-06-11T16:10:00.197
11

Suppose I have two functions DoTaskA and DoTaskB—both capable of throwing TaskException—with their corresponding "rollback" functions UndoTaskA and UndoTaskB. What is the best pattern to use so that either both succeed or both fail?

The best I have now is

bool is_task_a_done = false,
     is_task_b_done = false;

try {
    DoTaskA();
    is_task_a_done = true;

    DoTaskB();
    is_task_b_done = true;
} catch (TaskException &e) {
    // Before rethrowing, undo any partial work.
    if (is_task_b_done) {
        UndoTaskB();
    }
    if (is_task_a_done) {
        UndoTaskA();
    }
    throw;
}

I know that is_task_b_done is unnecessary, but maybe good to show code symmetry in case we add a third or a fourth task later on.

Don't like this code because of the auxiliary boolean variables. Perhaps there is something in the new C++11 that I'm not aware of, which can code this up more nicely?

Edit
Report

1 Answer

1

The best way to achieve this is with scope guards, basically a small RAII idiom that will invoke a rollback handler if an exception is thrown.

I've ask about a simple implementation of ScopeGuard a bit ago and the question evolved into a nice implementation i'm using in my production projects. It works with c++11 and lambdas as the rollback handlers.

my source has actually two versions: one that will invoke the rollback handler if the constructor handler throws, and another that will not throw if that happens.

check the source and usage examples in here.

answered 2012-06-11T16:54:42.610

Your Answer