9.2. The JDO Transaction Interface

9.2.1. Transaction Properties
9.2.2. Transaction Demarcation

The Transaction interface controls transactions in JDO. This interface consists of "getter" and "setter" methods for several Java bean-style properties and standard transaction demarcation methods.

[Note]Note

Kodo offers additional transaction-related functionality through the KodoPersistenceManager.

Kodo can also integrate with your application server's JTA service. See Section 8.2, “Integrating with the Transaction Manager” in the Reference Guide for details.

9.2.1. Transaction Properties

public boolean getNontransactionalRead ();
public void setNontransactionalRead (boolean read);
public boolean getNontransactionalWrite ();
public void setNontransactionalWrite (boolean write);
public boolean getRetainValues ();
public void setRetainValues (boolean retain);
public boolean getRestoreValues ();
public void setRestoreValues (boolean restore);
public boolean getOptimistic ();
public void setOptimistic (boolean optimistic);
public Synchronization getSynchronization ();
public void setSynchronization (Synchronization synch);

The Transaction's NontransactionalRead, NontransactionalWrite, RetainValues, RestoreValues, and Optimistic properties mirror those presented in Section 7.2.2, “PersistenceManager and Transaction Defaults”. We need not discuss them again.

The final Transaction property, Synchronization, has not been covered yet. This property enables you to associate a javax.transaction.Synchronization instance with the Transaction. The Transaction will notify your Synchronization instance on transaction completion events, so that you can implement custom behavior on commit or rollback. See the javax.transaction.Synchronization Javadoc for details.

[Note]Note

Kodo implements a complete transaction event listener framework in addition to the standard Synchronization callbacks mandated by the JDO specification.

9.2.2. Transaction Demarcation

public void begin ();
public void commit ();
public void rollback ();

The begin, commit, and rollback methods demarcate transaction boundaries. The methods should be self-explanatory: begin starts a transaction, commit attempts to commit the transaction's changes to the datastore, and rollback aborts the transaction, in which case the datastore is "rolled back" to its previous state. JDO implementations will automatically roll back transactions if any exception is thrown during the commit process.

public void setRollbackOnly ();
public boolean getRollbackOnly ();

In a large system, it is generally good practice to isolate transaction demarcation code from business logic. Your business methods should not begin and end transactions; that should be left to the calling code. In fact, declarative transaction frameworks like EJB's Container Managed Transactions (CMT) get rid of explicit transaction demarcation altogether.

Sometimes, though, your business methods may encounter an error that invalidates the current transaction. The setRollbackOnly method allows your business logic to mark the transaction for rollback. The method takes no parameters: once a transaction has been marked for rollback it cannot be unmarked. A transaction that has been marked for rollback cannot commit successfully. A call to commit will result in an exception and an automatic rollback. The getRollbackOnly method allows you to test whether the current transaction has been marked for rollback.

public boolean isActive ();

Finally, the isActive method returns true if the transaction is in progress (begin has been called more recently than commit or rollback), and false otherwise.

Example 9.1. Grouping Operations with Transactions

public void transferFunds (User from, User to, double amnt)
{
    // note: it would be better practice to move the transaction demarcation
    // code out of this method, but for the purposes of example...
    PersistenceManager pm = JDOHelper.getPersistenceManager (from);
    Transaction trans = pm.currentTransaction ();
    trans.begin ();
    try
    {
        from.decrementAccount (amnt);
        to.incrementAccount (amnt);
        trans.commit ();
    }
    catch (JDOFatalException jfe)  // trans is already rolled back
    {
        throw jfe;
    }
    catch (RuntimeException re)    // includes non-fatal JDO exceptions
    {
        trans.rollback ();         // or could attempt to fix error and retry
        throw re;
    }
}

 

Skip navigation bar   Back to Top