9.2. The JDO Transaction Interface
Prev | Chapter 9. Transaction | Next

## 9.2. The JDO Transaction Interface

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
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
Kodo implements a complete transaction event listener framework in addition to the standard `Synchronization` callbacks mandated by the JDO specification. See the `kodo.event` package Javadoc for details.

### 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;
        }
    }

Prev | Up | Next
Chapter 9. Transaction | Home | Chapter 10. Extent