9.7. Transaction Management

Within WAF, the Servlet Dispatchers handle all transactions for the developer. This document clarifies the decisions that have been made regarding transactions within the WAF, and briefly discusses how to manage transactions outside of the WAF.

9.7.1. Transactions within the WAF

The WAF imposes several restrictions on the developer that are important to understand:

One feature to realize is that if a SQLException is thrown when using Postgres then the transaction is aborted and it is no longer possible to interact with the database. Therefore, it is necessary to check for all conditions that could cause an error to arise before actually making a call to the database.

When programming in the WAF, unless you are writing a dispatcher or initializer, you will most likely not need to deal with transactions. However, if you do, the process is simple and is outlined in the next section.

9.7.2. Manual Transaction Management

When you manage your transactions locally, your starting point is the SessionManager class. From there, you can get access to the Session class and then to the Transaction. Specifically, the Session provides access to the TransactionContext, which has methods for beginning a transaction, committing a transaction, and aborting a transaction. For example, the following code will open a transaction, execute the necessary code and then either commit or abort the transaction:

import com.arsdigita.persistence.Session;
import com.arsdigita.persistence.SessionManager;
import com.arsdigita.persistence.TransactionContext;

Session session = SessionManager.getSession();
TransactionContext txn = session.getTransactionContext();

try {

    txn.beginTxn();

    // do some work here

    txn.commitTxn();

} catch (Exception e) {
    txn.abortTxn();
}

Transactions cannot be nested. If you have to make sure that you are in a transaction, use the inTxn() method of TransactionContext, as in the following example:

import com.arsdigita.persistence.Session;
import com.arsdigita.persistence.SessionManager;
import com.arsdigita.persistence.TransactionContext;

Session session = SessionManager.getSession();
TransactionContext txn = session.getTransactionContext();

boolean openedTransaction = false;
try {

    if (!txn.inTxn()) {
       openedTransaction = true;
       txn.beginTxn();
    }

    // do some work here

    if (openedTransaction) {
       txn.commitTxn();
    }
} catch (Exception e) {
    if (openedTransaction) {
        txn.abortTxn();
    }
}