libfossil
DB Transactions

The fsl_db_transaction_begin() and fsl_db_transaction_end() functions implement a basic form of recursive transaction, allowing the library to start and end transactions at any level without having to know whether a transaction is already in progress (sqlite3 does not natively support nested transactions).

A rollback triggered in a lower-level transaction will propagate the error back through the transaction stack and roll back the whole transaction, providing us with excellent error recovery capabilities (meaning we can always leave the db in a well-defined state).

It is STRICTLY ILLEGAL to EVER begin a transaction using "BEGIN" or end a transaction by executing "COMMIT" or "ROLLBACK" directly on a db handle which associated with a fsl_cx instances. Doing so bypasses internal state which needs to be kept abreast of things and will cause Grief and Suffering (on the client's part, not mine).

Tip: implementing a "dry-run" mode for most fossil operations is trivial by starting a transaction before performing the operations. Many operations run in a transaction, but if the client starts one of his own he can "dry-run" any op by simply rolling back the transaction he started. Abstractly, that looks like this pseudocode:

db.begin();
fsl.something();
fsl.somethingElse();
if( dryRun ) db.rollback();
else db.commit();