next up previous contents
Next: The Shore Error Up: Handling Errors in a Previous: The shrc Class

 

Macros for Transaction Management

The most common way to handle errors in database systems is to abort the transaction that caused the error. Application programs can abort their transactions by calling Shore::abort_transaction. While this method causes any changes to persistent data to be be undone, it does not affect the state of the application program. Shore provides macros to begin, commit, and abort transactions that can help to address part of this problem. The macros employ ANSI C setjmp and longjmp facilities.

The four macros are:

    SH_BEGIN_TRANSACTION(rc)        // rc is an ``out'' parameter
    SH_ABORT_TRANSACTION(rc)        // rc is an ``in''  parameter
    rc = SH_COMMIT_TRANSACTION
    SH_DO(rc)                       // rc is an ``in''  parameter

These macros are summarized in the manual page transaction(OC).

The argument to SH_BEGIN_TRANSACTION is of type shrc. This argument must be an lvalue, as the macro will assign to it. SH_BEGIN_TRANSACTION calls setjmp, and can therefore return from either of two different contexts: a direct call to SH_BEGIN_TRANSACTION, or a call to SH_ABORT_TRANSACTION (described below). A direct call to SH_BEGIN_TRANSACTION calls Shore::begin_transaction. Upon return, rc will be set to the return value of Shore::begin_transaction.. When SH_BEGIN_TRANSACTION returns because of a call to SH_ABORT_TRANSACTION, then the value of rc is whatever was passed to SH_ABORT_TRANSACTION.

SH_COMMIT_TRANSACTION is equivalent to Shore::commit_transaction.

SH_ABORT_TRANSACTION takes as parameter an expression of type shrc. (Unlike SH_BEGIN_TRANSACTION, this argument is an rvalue, not an lvalue). It calls Shore::abort_transaction and then performs a longjmp, which returns control back to the line where SH_BEGIN_TRANSACTION was called. The rc passed to SH_ABORT_TRANSACTION will be the return value of SH_BEGIN_TRANSACTION.

SH_DO takes an expression of type shrc. If this expression evaluates to RCOK then the macro returns. Otherwise, SH_ABORT_TRANSACTION is called with the value of the given expression as its argument.

The following code fragment the use of the transaction macros.

    shrc rc;

    // Begin a transaction.  A subsequent call to SH_ABORT_TRANSACTION
    // will return us here.
    SH_BEGIN_TRANSACTION(rc);

    if(rc){

        // Some error occurred.  The rc indicates why new transaction could
        // not be started or why the transaction was aborted.
        cerr << rc << endl;
    }

    else {


        // We successfully started a transaction.  The main body of the
        // transaction goes here. 

        SH_DO(operation 1);
        SH_DO(operation 2);
        SH_DO(...);


        // If we completed the main body of the transaction without
        // errors, then we try to commit the transaction.  Note that
        // if the commit fails, then SH_DO will call SH_ABORT_TRANSACTION
        // for us.  The shrc returned by SH_COMMIT_TRANSACTION will become
        // the the return value of SH_BEGIN_TRANSACTION (above).

        SH_DO(SH_COMMIT_TRANSACTION);
    }

Note that because these macros make use of setjmp and longjmp, the function containing the call to SH_BEGIN_TRANSACTION must not have terminated before SH_DO or SH_ABORT_TRANSACTION is called. However, a call to SH_COMMIT_TRANSACTION, SH_DO, or SH_ABORT_TRANSACTION does not have to be in the same function as the call to SH_BEGIN_TRANSACTION. In particular, it may be useful to call SH_ABORT_TRANSACTION from within the Shore error handler function, which is described in the next section.



next up previous contents
Next: The Shore Error Up: Handling Errors in a Previous: The shrc Class



Marvin Solomon
Fri Aug 2 13:39:50 CDT 1996