Show TOC Start of Content Area

Component documentation Transactions in JDO  Locate the document in its SAP Library structure

Purpose

Transactions are a central concept in persistency. They are defined as single units of work, which possess four characteristics, known as ACID – atomicity, consistency, isolation, and durability.

In JDO you need to use transactions when the access to the underlying data store is transactional – that is, if you need to change the persistent data.

The transaction management differs when you use JDO in a managed or in a non-managed environment. While in the non-managed scenario, the JDO-aware application is responsible for the transaction startup and completion, in managed environments (J2EE application server) transaction management may be delegated to an external system – in J2EE Engine, it is the Transaction Service.

The application developer may also choose to implement the transactional logic in the application component. The JDO API provides the javax.jdo.Transactioninterface, which enables you to demarcate local transactions programmatically. To demarcate distributed transactions programmatically, you use the javax.transaction.UserTransaction interface.

The JDO standard defines the following transaction scenarios:

·        Datastore – the default scenario, which the JDO implementation is required to support

·        Optimistic – an optional scenario

The SAP JDO implementation supports optimistic transactions.

Integration

Although the JDO standard is not a part of J2EE, it is designed to enable the seamless integration of JDO implementations within the J2EE application servers, such as the J2EE Engine. The engine provides the SAP JDO implementation with:

·        Transaction management

·        Implementation of the J2EE Connector Architecture

Using these functions, the developers of JDO-aware applications can focus on the application design itself, instead of putting effort into implementing component-managed transactions and connectivity.

However, there are certain cases when you may choose to implement programmatic (component-managed) transaction demarcation. You can use the following interfaces:

·        javax.transaction.UserTransaction – according to the JTA (Java Transaction API) specification, this is the standard interface for demarcating distributed transactions programmatically. The UserTransaction object is either obtained by a lookup operation from the JNDI registry, or by retrieving it from an enterprise bean’s context. The UserTransaction’s begin(), commit(), and rollback() methods demarcate a JTA transaction – that is, a global transaction coordinated by the J2EE server.

For more information about the UserTransaction interface, see Using Component-Managed JTA Transactions.

Recommendation

We recommend the use of JTA transactions in the communication with the persistence layer.

When using such transactions, you should always obtain the PersistenceManager instance within the transaction boundaries.

·        javax.jdo.Transaction – this interface is used for local transaction demarcation. Its methods are discussed in more details next. For more information about local transactions, see Using Local Transactions.

Features

The javax.jdo.Transaction Interface

An instance of this interface maintains a one-to-one relationship to a Persistence Manager (PM) instance. To obtain the transaction object associated to the PM you use, you have to invoke the currentTransaction() method. Each time you invoke this method on the same PM, you will obtain the same transaction instance.

Example

pm = pmf.getPersistenceManager();

Transaction tx = pm.currentTransaction();

 

To demarcate the transaction boundaries, you can use the begin(), commit() and rollback() methods of the Transaction interface.

The interface provides a method getPersistenceManager(), which returns the PM instance associated to the transaction object.

The Transaction interface also enables you to define the use of cache. The value of the relevant parameter is managed by getter and setter methods, similarly to a JavaBean’s properties.

You can manage the use of optimistic transactions with the setOptimistic() method. This is explained in more detail in the next section.

In addition, you can choose to allow non-transactional read or write operations – that is, to enable reading and modifications of persistent field values outside a transaction on hollow or persistent-nontransactional instances.

The use of cache is defined by the retainValues and restoreValuesparameters. If the restoreValues option is set to true, the values of the changed fields are kept in the cache, and in case of a rollback, they are restored as the instance transitions to persistent non-transactional. If set to false, the dirty instance transitions to hollow and the values of its fields are not restored. The retainValues option defines if the new values of the persistent fields are kept in the cache after the transaction has been committed. If the option is set to true, the instance transitions to persistent-nontransactional and keeps the valid values of the fields cached. If the option is set to false, the instance transitions to a hollow state.

When used in a distributed environment, as in the J2EE Engine, the implementation of the Transaction interface also implements javax.transaction.Synchronization. This enables the transaction management system to invoke beforeCompletion() or afterCompletion() methods on the transaction object. In addition, you can implement the Synchronization interface yourself, and register it with the transaction object to get notification for the instance’s state transitions:

Example

pm = pmf.getPersistenceManager();

Transaction tx = pm.currentTransaction();

tx.setSynchronization(mySynchronizationImpl);

 

Optimistic Transactions

In optimistic transactions, locking is done by the database and depends entirely on the transaction isolation level (Open SQL supports TRANSACTION_READ_UNCOMMITTED and TRANSACTION_READ_COMMITTED only). The JDO implementation itself does not impose implicit locking. The locks are released after committing the transaction. In addition, the WHERE clause of the update statements provides a before image of the data; thus, at commit time data it is checked for consistency.

The SAP JDO implementation supports optimistic transactions as a default scenario. Therefore, to run an optimistic transaction, you do not need to set its Optimistic property explicitly to true. The following code demarcates an optimistic transaction:

Example

pm = pmf.getPersistenceManager();

Transaction tx = pm.currentTransaction();

tx.begin();

Department dep = new Department(depId);

dep.setName(name);

pm.makePersistent(dep);

tx.commit();

 

Using the API, you can set the Optimistic property to false by calling Transaction.setOptimistic(false). In this mode batching is applied for update statements.

If you need a higher level of concurrency control, in addition to setting the Optimistic property to false, you must use explicit locking. For more information, see Locking.

Supported Options in the SAP Implementation. The Default PMF

The SAP JDO implementation supports the following optional features related to the JDO transaction management:

·        javax.jdo.option.NontransactionalRead

·        javax.jdo.option.NontransactionalWrite

·        javax.jdo.option.RestoreValues

·        javax.jdo.option.RetainValues

·        javax.jdo.option.Optimistic

·        javax.jdo.option.TransientTransactional

In the J2EE Engine managed environment, the JDO implementation is deployed as a resource adapter and provides a preconfigured PersistenceManagerFactory (PMF) to the JDO-aware applications. They look up the PMF from the naming system using the string java:comp/env/jdo/defaultPMF. The PMF provides PM instances. Its configuration defines the options that are enabled by default for the JDO transactions and the queries associated to the PMs.

In the default PMF configuration, the optimistic transaction support is enabled (the value of the Optimistic property is set to true). The nontransactional read is enabled, but data cannot be modified outside a transaction (the NontransactionalWrite option is false). The RetainValues and the RestoreValues options are also set to false. The default configuration also sets the IgnoreCache property to true, which means that optimistically changed data in the cache is not considered in queries. This option is used for performance improvement when executing queries.

For more information about the settings of the default PMF, see The Default PersistenceManagerFactory.

 

 

End of Content Area