Using or Ignoring the Cache in a Query


Each persistence manager controls a cache of persistent application data objects in memory. When a transaction is active, the persistent objects can become transactional. JDO assumes responsibility for the consistency of transactional and persistent objects with the corresponding state in the datastore. If these objects are modified, JDO assumes responsibility for synchronizing their changed state with the datastore before the transaction commits.

When the query ignores the cache, the persistent and transactional objects in the cache are not considered when determining the query results. On the other hand, when the query uses the cache, the modified state in the cache may determine the query results. This modified state includes the state of persistent-dirty, persistent-new, and persistent-deleted objects in the cache.

Consider the Truck objects described in Table 2-4. Before the transaction begins, there are three trucks, T1, T2, and T3, that are all painted red. After the transaction begins, the three trucks are retrieved and loaded into the cache. During the transaction, the T1 truck is deleted. A new T4 truck with the color blue is made persistent, and the color of the T3 truck is changed to blue. (For simplicity, the Truck class represents the truck's color in a String field named, appropriately, color.)

Table 2-4: The Cached State of Red and Blue Trucks Prior to Query Execution

Identity

Color

Management State

T1

Red

Persistent-deleted

T2

Red

Persistent-clean or persistent-nontransactional

T3

Blue

Persistent-dirty (color changed)

T4

Blue

Persistent-new

When the application uses the two query filters

 "color == \"red\"" "color == \"blue\"" 

which trucks are found? For the first query, if the cache is not ignored, then only T2 is found. T1 and T2 are not found because T1 has been deleted and T3's color has changed to blue. On the other hand, if the cache is ignored, then T1, T2, and T3 are found, because the changes in memory do not affect the query results. The second query has a similar story. If the cache is not ignored, then T3 and T4 are found; otherwise, no blue trucks are found.

The query inherits the value of its IgnoreCache property from the persistence manager that produced it. When the query's IgnoreCache property is false, it determines the query's behavior, but when it is true, it is only a hint. When the query ignores the cache, the specification does not make it clear whether JDO is guaranteeing to ignore all the changes or only so many of them as is convenient. On the other hand, if the query is directed to not ignore the cache, then the query must consider all the changes in the cache that could affect the query's results.

The setting of the IgnoreCache flag affects query results only when three conditions are met. First, the transaction for the query's persistence manager must be active. When the transaction is not active, there are no persistent-new, persistent-deleted, or persistent-dirty objects in the cache. Second, the query must run in the datastore. If the query runs in memory, then the uniqueness requirement ensures that cached objects are used. Third, some persistent objects must have been added, deleted, or modified in the transaction. Setting the IgnoreCache flag to true or false never alters the query results unless these three conditions are met.

Applications use the IgnoreCache flag to trade off accuracy in the query results for better performance. To understand how the IgnoreCache flag may affect performance, it is helpful to consider some implementation details. By flushing the changes in the cache to the datastore before sending the query to the datastore, the JDO implementation ensures that the query results reflect the changes in memory. (There may be other ways to accomplish the same objective, but this is the obvious way to do it.)

Although flushing before the query is extra work, it is more work in some cases than in others. In a datastore transaction, the flush needs to occur only once for each modification. Because a datastore transaction keeps the database transaction open, the work done in the flush is not lost, and the flush would have to occur anyway when the transaction commits. On the other hand, in an optimistic transaction, the same modifications might be flushed more than once. Since an optimistic transaction prefers to close the database transaction as soon as possible, the same modifications might be flushed for every query execution.

As a general rule then, the time to consider setting the query's IgnoreCache flag to true is when the application executes queries in optimistic transactions after modifications have been made. If this situation is avoided, then the recommended action is to set the flag to false.




Using and Understanding Java Data Objects
Using and Understanding Java Data Objects
ISBN: 1590590430
EAN: 2147483647
Year: 2005
Pages: 156
Authors: David Ezzio

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net