Next: , Up: Transactions and topological sorting



6.3.1 How to use transactions

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):