The best way to understand the purpose and effect of the five transactional properties is to understand how the property settings affect JDO's actions, whether implicit or explicit, when they alter the managed state of application data objects. Quite a few diagrams are presented in this section. Each diagram shows changes in the object's management state that result from JDO actions under the different settings of the transactional properties. Their purpose is to provide more than enough detail to
There are four possible combinations of the two nontransactional properties. Since there is no apparent use for turning on
NontransactionalWrite
without also turning on
NontransactionalRead
, this case is not
Figure 4-3 illustrates the state transitions of an application data object when the allowed persistent operations are performed outside of a transaction and when
NontransactionalRead
(NTR) is true and
NontransactionalWrite
(NTW) is false. In this transactional configuration, there are only three management states that application data objects can be in. These states are the three nontransactional states in JDO. The other seven management states are all transactional states. All of them, except the transient-clean state, are therefore not possible when a transaction is not active. The transient-clean state is discussed in the section "The Optional
Figure 4-3:
State transitions outside a transaction when NTR is true and NTW is false
When an application data object is hollow, all of its persistent field values are cleared except for its key fields. An application data object has one or more persistent key fields only when its class uses application identity. When a key field of a hollow object is accessed, the object remains hollow. When a persistent, non-key field of a hollow object is accessed, the value of the field is loaded from the datastore and the object becomes persistent-nontransactional. Once in memory, the field's value is not loaded again, unless it is refreshed or evicted. Outside a transaction, persistent application data objects, whether hollow or
Figure 4-4 illustrates the state transitions of an application data object when the allowed persistent operations are performed outside of a transaction and when both
NontransactionalRead
and
NontransactionalWrite
are true. The state transitions permitted here are very similar to those permitted for the transactional configuration of Figure 4-3, except that now both reads and
Figure 4-4:
State transitions outside a transaction when both NTR and NTW are true
The three properties,
Optimistic
,
RetainValues
, and
RestoreValues
, control JDO's actions on managed objects within a transaction. Before looking at how JDO behaves when these properties are turned on or off, it is helpful to examine all of JDO's actions within a transaction that are not affected by these properties. Of the ten management states for application data objects, five are persistent and transactional, two are persistent but not transactional, and one is
For the eight management states that are not transient and transactional, Figure 4-5 shows all the JDO actions that can occur within transactions and meet the following four conditions:
The effects of the action are the same regardless of the settings of the Optimistic , RetainValues , or RestoreValues properties.
The action is allowed (i.e., it does not throw an exception).
Either the action results in a state change, or it is not obvious that the state would not change.
The action does not make use of the optional JDO transient-transactional feature.
Figure 4-5:
State transitions common to all transactions
Although the diagram of state transitions in Figure 4-5 is complex, there are a few simple principles that organize the complexity. Objects in any of the persistent states can be deleted, but persistent-new objects transition to the persistent-new-deleted state rather than the
As Figure 4-5 shows, the makeNontransactional method changes persistent-clean objects to persistent-nontransactional. If the JDO implementation does not support the javax.jdo.option.NontransactionalRead option, then calling makeNontransactional for a persistent-clean object results in a JDOUnsupportedOptionException .
Figure 4-5 provides the background for the figures that follow. While Figure 4-5 shows the actions that are independent of the three properties, Optimistic , RetainValues , and RestoreValues , the figures that follow show the actions that are dependent on the values of one of these properties.
Figure 4-6 shows the operations whose behavior is unique to a datastore transaction. A JDO transaction is a datastore transaction when the transaction's
Optimistic
property is set to false. The persistent-clean state is central to the datastore transaction. When an application data object is in the persistent-clean state, its persistent state is
Figure 4-6:
State transitions unique to datastore transactions
Reading a persistent non-key field of a hollow application data object or passing the application data object to
makeTransactional
causes JDO to change the object to persistent-clean. When the application data object is persistent-nontransactional, reading a persistent non-key field in the object causes JDO to discard the object's existing persistent state during the change to persistent-clean. Usually, the implementation loads the default fetch
Refreshing a persistent-dirty object causes JDO to discard the persistent state, including the modifications made. The object reverts to persistent-clean. Some JDO implementations may be able to restore the correct transactional values for the persistent fields from the before-image, while others may need to reload the correct values from the datastore.
{% if main.adsdop %}{% include 'adsenceinline.tpl' %}{% endif %}Interestingly, passing a persistent-nontransactional object to the refresh method may be a no-op in a datastore transaction. In a datastore transaction, there is little reason for the implementation to carry out the refresh actions on a persistent-nontransactional object, since either read or write access to the persistent fields causes an implicit refresh.
Figure 4-7 illustrates the behavior that is unique to optimistic transactions. A transaction is optimistic when its
Optimistic
property is set to true. The figure shows behavior for optimistic transactions that is strikingly different from the behavior diagrammed for datastore transactions in Figure 4-6. In the optimistic transaction, the persistent-nontransactional state is central. When a non-key, persistent field of a hollow object is accessed, the object changes to persistent-nontransactional. Reading any field of a persistent-nontransactional object
Figure 4-7:
State transitions unique to optimistic transactions
If a persistent-nontransactional object is made transactional, the persistent state is not refreshed before the object becomes persistent-clean. Instead of reloading the persistent state (and possibly locking it) as would happen in a datastore transaction, the optimistic transaction enforces transactional consistency by checking the concurrency value of all transactional objects during commit processing.
Within an optimistic transaction, when the application writes to a persistent field of a persistent-nontransactional object, the object's state changes to persistent-dirty. Before the write is applied, the persistent fields of the object are not refreshed. Rather, the existing values of the persistent fields are kept.
A refresh on a persistent-nontransactional object causes the persistent state to be discarded. JDO
Figure 4-8 illustrates the behavior that is unique to transactions when the Retain-Values property is false. As Figure 4-8 shows, application data objects that are both persistent and transactional become either hollow or JDO-transient upon transaction commit when RetainValues is false. Whether they become hollow or JDO-transient, JDO clears their persistent fields.
Figure 4-8:
State transitions upon commit when RetainValues is false
Application data objects that are not transactional are not affected by transaction completion. In particular, the commit method has no effect on objects that are in the hollow, persistent-nontransactional, or JDO-transient state. As a result, setting the RetainValues property to false does not automatically evict persistent-nontransactional objects when the transaction commits.
Figure 4-9 illustrates the behavior that is unique to transactions when the RetainValues property is true. As Figure 4-9 shows, application data objects that are both transactional and persistent become either persistent-nontransactional or JDO-transient upon transaction commit when RetainValues is true. Whether they become persistent-nontransactional or JDO-transient, JDO retains the values of their persistent fields.
Figure 4-9:
State transitions upon commit when RetainValues is true
Application data objects that are not transactional are not affected by transaction completion. In particular, a call to the commit method has no effect on objects that are in the hollow, persistent-nontransactional, or JDO-transient state.
Figure 4-10 illustrates the behavior that is unique to transactions when the RestoreValues property is false. As Figure 4-10 shows, when RestoreValues is false, all transactional objects become either hollow or JDO-transient upon transaction rollback. The persistent fields of persistent-clean, persistent-dirty, and persistent-deleted application data objects are cleared to their Java default values on rollback.
Figure 4-10:
State transitions upon rollback when RestoreValues is false
As a result of both rollback and the automatic eviction, the objects become hollow. On the other hand, on rollback when RestoreValues is false, JDO retains the values of the persistent fields of persistent-new and persistent-new-deleted objects.
Application data objects that are not transactional are not affected by transaction completion. In particular, the rollback method has no effect on objects that are in the hollow, persistent-nontransactional, or JDO-transient state.
Figure 4-11 illustrates the behavior that is unique to transactions when strong RestoreValues is true. As Figure 4-11 shows, all transactional objects become hollow, persistent-nontransactional, or JDO-transient upon transaction rollback when strong RestoreValues is true. Persistent-clean objects do not have a before-image. As a result, they change to persistent-nontransactional upon rollback.
Figure 4-11:
State transitions upon rollback when strong RestoreValues is true
Persistent-dirty and persistent-deleted objects may become hollow or persistent-nontransactional. They become hollow because they previously changed to the persistent-dirty or persistent-deleted state from the hollow state. As a result, the before-image contains the Java default values for the persistent fields. On the other hand, if the persistent-dirty or persistent-deleted objects were previously persistent-clean or persistent-nontransactional, then they become persistent-nontransactional as a result of restoring from the before-image upon rollback.
Application data objects that are not transactional are not affected by transaction completion. In particular, the rollback method has no effect on objects that are in the hollow, persistent-nontransactional, or JDO-transient state.
Figure 4-12 illustrates the behavior that is unique to transactions when weak RestoreValues is true. As Figure 4-12 shows, persistent-new and persistent-new-deleted objects become JDO-transient upon transaction rollback when weak RestoreValues is true. Persistent-clean, persistent-dirty, and persistent-deleted objects become hollow.
Figure 4-12:
State transitions upon rollback when weak RestoreValues is true
If you compare Figure 4-12 with Figure 4-10, you can see that the state transitions when
RestoreValues
is weak are the same whether the property is true or false. All that changes is whether JDO saves a before-image when the object becomes persistent-new and whether JDO