The transaction interface is similar to those of some other programming languages:
TRANS_BEGIN_MAIN( transaction_tlo, undo_item_description, error_buffer ) { // do something if (something_nasty) trans_fail("Something nasty ocurred."); // ... } TRANS_FAILED { // Error handler. if (too_nasty) trans_fail("Something too nasty occured."); else msg("This happened: %s", error_buffer); } TRANS_END
The transactions are implemented using the goto
, return
and longjmp
commands.
Jumping into and out of the transaction block is forbidden. Inside of a transaction, any other
functions can be called without restrictions.
The only method to break the current transaction is to call the trans_fail
function.
When this function is called, the current transaction is broken and the error handler is executed.
void trans_fail(const char* format, ...)
The trans_fail
function leaves all nested functions and does a long jump to
the beginning of the error handler.
It accepts the same arguments as printf
and the resulting message is stored in
the error_buffer
which is an array of characters.
The length of the array must be TRANS_ERR_SIZE
.
The transactions can be nested – a transaction can be called inside another transaction.
When a nested transaction finishes
(successfully or unsuccessfuly), the code execution continues after the TRANS_END
of the transaction. The trans_fail
function can be called in the
error handler of a nested transaction, which causes a fail of the superior transaction.
Thus the exception can be propagated.
There are three ways to start a transaction (the rest is the same):
TRANS_BEGIN_MAIN
– starts a new transaction with the given TLO.
This should be used when you are unsure if
a transaction for the desired transaction TLO is already on the transaction stack.
TRANS_BEGIN
– starts a new nested transaction with the current transaction
tlo. This is useful if you want to prevent possible errors from causing the fail of the
whole current transaction.
TRANS_BEGIN_ANONYMOUS
– for transactions which create no undo history
items; useful when you just want to use the transaction exception mechanism.