14.2 Reading Outside a Transaction

NontransactionalRead allows your application to access the datastore without ever beginning a transaction; it also allows you to access the datastore and read cached instances and fields between completing one transaction and beginning the next. This allows read-only applications nearly full access to the features of JDO, without the overhead of beginning and completing transactions. Access in the NontransactionalRead case includes iterating extents, querying the datastore, accessing persistent field values, and navigating among instances using persistent relationships.

Note that you must always have an active transaction in order to insert new persistent instances, delete existing instances, or change existing data in the datastore.

One use for the NontransactionalRead mode of operation is to access slowly changing information. For example, access to the MediaContent instances can be nontransactional, because in most cases the information is static. At times, the datastore might be updated with new MediaContent instances, but for the most part, the information does not change.

When executing your application outside a transaction, the cache contains persistent instances whose field values came from the datastore, but there is no guarantee that the field values are consistent with the current datastore contents, or are even consistent with other field values from the same persistent instance. This is because field values are retrieved from the datastore on demand.

For example, if you query the datastore and access a field in a persistent instance, the JDO implementation might retrieve only the field accessed. A subsequent read of a different field might come from the cache or might result in a datastore access to retrieve the current value from the datastore. None of the field values retrieved earlier will be refreshed from the datastore, so the persistent instance might contain fields that represented the datastore at different times.

Therefore, before using this mode, make sure that dirty reads are acceptable for correct operation of your application.

Another common pattern is to use nontransactional read to navigate an object graph to locate a particular instance, and then begin a transaction to update the instance. This is possible because the identity of every instance in the cache is known, even though the field values are nontransactional.

Nontransactional instances in the cache will remain nontransactional even if a transaction is subsequently begun. If they are not accessed during subsequent transactions, they will remain nontransactional.

If your application accesses nontransactional instances during a datastore transaction, they become transactional at the time of the first access in the transaction. When this happens, the JDO implementation discards the cached field values and, just as for hollow instances, retrieves transactionally consistent field values from the datastore.

If your application accesses nontransactional instances for read during an optimistic transaction, they will remain nontransactional and might not be refreshed unless your application explicitly refreshes them by calling PersistenceManager.refresh( ).