We have already seen that the commit() function that is used to commit an action and disarm the rollback guard must never throw an exception. Fortunately, that is easy to guarantee since all this function does is set a flag. But what happens if the rollback function also fails, and throws an exception?
void Database::insert(const Record& r) { S.insert(r); auto SF = MakeGuard([&] { S.finalize(); }); auto SG = MakeGuard([&] { S.undo(); }); // What if undo() can throw? I.insert(r); // Let's say this fails SG.commit(); // Commit never happens} // Control jumps here and undo() throws
The short answer is nothing good. In general, we have a conundrum—we cannot allow the action, in our case the storage insertion, ...