Oracle9i Application Server Oracle9iAS Object Caching Service for Java Developer's Guide Release 1 (v1.0.2.2) Part Number A88852-01 |
|
The Object Caching Service for Java supports two modes of operation, local mode and distributed mode. Using local mode, objects are isolated to a single Java VM process and are not shared. Using distributed mode, the Object Caching Service for Java can propagate object changes - including invalidations, destroys, and replaces- through the cache's messaging system to other communicating caches running either on a single system or across a network (the Object Caching Service for Java messaging system is built on top of TCP/IP).
This chapter covers the following topics:
When running in local mode, the Object Caching Service for Java does not share objects or communicate with any other caches running locally on the same machine or remotely across the network. Local mode provides a decentralized architecture that supports a very efficient cache system, with very limited overhead. Object persistence across system shutdowns or program failures is not supported when running in local mode.
By default, the Object Caching Service for Java runs in local mode and all objects in the cache are treated as local objects. When the Object Caching Service for Java is configured in local mode, the cache ignores the DISTRIBUTE
attribute for all objects.
In distributed mode, the Object Caching Service for Java can share objects and communicate with other caches running either locally on the same machine or remotely across the network. Object updates and invalidations are propagated between communicating caches. Distributed mode supports object persistence across system shutdowns and program failures. Running in distributed mode has possible disadvantages. Specifically, significant system resources may be required when a large number of distributed objects need to be invalidated, when very large objects are updated, or when updates must be performed rapidly.
This section covers the following topics:
To configure the Object Caching Service for Java to run in distributed mode, set the value of the distribute
and discoveryAddress
configuration properties in the OCS4J.properties
file.
To start the Object Caching Service for Java in distributed mode, the distribute
property should be set to true
in the configuration file.
In distributed mode, invalidations, destroys, and replaces are propagated through the cache's messaging system. The messaging system requires a known hostname and port address to allow a cache to join the cache system when it is first initialized. Use the
discoveryAddress
property in the OCS4J.properties
file to specify a list of hostname and port addresses.
By default, Object Caching Service for Java sets the discoveryAddress
to the value :12345
(this is equivalent to localhost:12345
). To eliminate conflicts with other software on the site, you should have your system administrator set the discoveryAddress
.
If the caching service spans systems, a comma separated list of hostname and port pairs should be included as the value for discoveryAddress
, with one hostname:port
pair specified for each node. This avoids any dependency on a particular machine being available or on the order the processes are started.
When the Object Caching Service for Java runs in distributed mode, individual regions, subregions, groups, and objects can be either local, or distributed. By default, objects, regions, subregions, and groups are defined as local. To change the default local value, set the DISTRIBUTE
attribute when the object, region, or group is defined.
A distributed cache may contain both local and distributed objects.
Several attributes and methods in the Object Caching Service for Java allow you to work with distributed objects and control the level of consistency of object data across the caches.
When updating, invalidating, or destroying objects across multiple caches, it is useful to know when the action has completed at all the participating sites. Setting the REPLY
attribute causes all participating caches to send a reply to the sender when a requested action has completed for the object with the REPLY
attribute set. This also enables the wait for response feature for object updates, invalidates, or destroys, and requires the use of the blocking method CacheAcces.waitForResponse()
.
To wait for a distributed action to complete across multiple caches, use CacheAccess.waitForResponse()
. To ignore responses, use the CacheAccess.cancelResponse()
method, which frees the cache resources used to collect the responses.
Both CacheAccess.waitForResponse()
and CacheAccess.cancelResponse()
apply to all objects accessed by the CacheAccess
object. This allows the application to update a number of objects, then wait for all the replies.
Example 5-1 illustrates how to set an object as distributed and handle replies when the REPLY
attribute is set. In this example, the attributes may also be set for the entire region. Attributes could also be set for a group or individual object, as appropriate for your application.
import oracle.ias.cache.*; CacheAccess cacc; String obj; Attributes attr = new Attributes (); MyLoader loader = new MyLoader(); // mark the object for distribution and have a reply generated // by the remote caches when the change is completed attr.setFlags(Attributes.DISTRIBUTE|Attributes.REPLY); attr.setLoader(loader); CacheAccess.defineRegion("testRegion",attr); cacc = CacheAccess.getAccess("testRegion"); // create region with distributed attributes obj = (String)cacc.get("testObject"); cacc.replace("testObject", obj + "new version"); // change will be propagated to other caches cacc.invalidate("invalidObject"); // invalidation is propagated to other caches try { // wait for up to a second,1000 milliseconds, for both the update and the invalidate to complete cacc.waitForResponse(1000); catch (TimeoutException ex) { // tired of waiting so cancel the response cacc.cancelResponse(); } cacc.close(); }
When updating objects across multiple caches, or when multiple threads access a single object, you may coordinate the update action. Setting the SYNCHRONIZE
attribute enables synchronized updates and requires an application to obtain ownership of an object before the object is loaded or updated.
The SYNCHRONIZE
attribute also applies to regions, subregions, and groups. When the SYNCHRONIZE
attribute is applied to a region, subregion, or group, ownership of the region, subregion, or group must be obtained before an object can be loaded or replaced in the region, subregion, or group.
Setting the SYNCHRONIZE_DEFAULT
attribute on a region, subregion, or group applies the SYNCHRONIZE
attribute to all of the objects within the region, subregion, or group. Ownership must be obtained for the individual objects within the region, subregion, or group before they can be loaded or replaced.
To obtain ownership of an object, use CacheAccess.getOwnership()
. Once ownership is obtained, no other CacheAccess
instance is allowed to load or replace the object. Reads and invalidation of objects are not affected by synchronization.
Once ownership has been obtained and the modification to the object is completed, call
CacheAccess.releaseOwnership()
to release the object. CacheAccess.releaseOwnership()
waits up to the specified time for the updates to complete at the remote caches. If the updates complete within the specified time, ownership is released, otherwise a TimeoutException
is thrown. If the method times out, call CacheAccess.releaseOwnership()
again. CacheAccess.releaseOwnership()
must return successfully for ownership to be released. If the time out value is -1
, ownership is released immediately without waiting for the responses from the other caches.
import oracle.ias.cache.*; CacheAccess cacc; String obj; Attributes attr = new Attributes (); MyLoader loader = new MyLoader(); // mark the object for distribution and set synchronize attribute attr.setFlags(Attributes.DISTRIBUTE|Attributes.SYNCHRONIZE); attr.setLoader(loader); //create region CacheAccess.defineRegion("testRegion"); cacc = CacheAccess.getAccess("testRegion"); cacc.defineGroup("syncGroup", attr); //define a distributed synchronized group cacc.defineObject("syncObject", attr); // define a distributed synchronized object attr.setFlagsToDefaults() // reset attribute flags // define a group where SYNCHRONIZE is the default for all objects in the group attr.setFlags(Attributes.DISTRIBUTE|Attributes.SYNCHRONIZE_DEFAULT); cacc.defineGroup("syncGroup2", attr); try { // try to get the ownership for the group don't wait more than 5 seconds cacc.getOwnership("syncGroup", 5000); obj = (String)cacc.get("testObject", "syncGroup"); // get latest object // replace the object with a new version cacc.replace("testObject", "syncGroup", obj + "new version"); obj = (String)cacc.get("testObject2", "syncGroup"); // get a second object // replace the object with a new version cacc.replace("testObject2", "syncGroup", obj + "new version"); } catch (TimeoutException ex) { System.out.println("unable to acquire ownership for group"); cacc.close(); return; } try { cacc.releaseOwnership("syncGroup",5000); } catch (TimeoutException ex) { // tired of waiting so just release ownership cacc.releaseOwnership("syncGroup", -1)); } try { cacc.getOwnership("syncObject", 5000); // try to get the ownership for the object // don't wait more than 5 seconds obj = (String)cacc.get("syncObject"); // get latest object cacc.replace("syncObject", obj + "new version"); // replace the object with a new version } catch (TimeoutException ex) { System.out.println("unable to acquire ownership for object"); cacc.close(); return; } try { cacc.releaseOwnership("syncObject", 5000); } catch (TimeoutException ex) { cacc.releaseOwnership("syncObject", -1)); // tired of waiting so just release ownership } try { cacc.getOwnership("Object2", "syncGroup2", 5000); // try to get the ownership for the object // where the ownership is defined as the default for the group don't wait more than 5 seconds obj = (String)cacc.get("Object2", "syncGroup2"); // get latest object // replace the object with new version cacc.replace("Object2", "syncGroup2", obj + "new version"); } catch (TimeoutException ex) { System.out.println("unable to acquire ownership for object"); cacc.close(); return; } try { cacc.releaseOwnership("Object2", 5000); } catch (TimeoutException ex) { cacc.releaseOwnership("Object2", -1)); // tired of waiting so just release ownership } cacc.close(); }
Within the Object Caching Service for Java, each cache manages its own objects locally within its Java VM process. In distributed mode, when using multiple processes or when the system is running on multiple sites, a copy of an object may exist in more than one cache.
The Object Caching Service for Java allows you to specify the consistency level required between copies of objects that are available in multiple caches. The consistency level you specify depends on the application and the objects being cached. The supported levels of consistency vary, from none, to all copies of objects being consistent across all communicating caches.
Setting object attributes specifies the level of consistency. The consistency between objects in different caches is categorized into the following four levels:
If there are no consistency requirements between objects in distributed caches, an object should be defined as a local object (when Attributes.DISTRIBUTE
is unset, this specifies a local object). Local is the default setting for objects. For local objects, all updates and invalidation are only visible to the local cache.
To distribute object updates across distributed caches, an object should be defined as distributed by setting the DISTRIBUTE
attribute. All modifications to distributed objects are broadcast to other caches in the system. Using this level of consistency does not control or specify when an object is loaded into the cache or updated, and does not provide notification as to when the modification has completed in all caches.
To distribute object updates across distributed caches and wait for the change to complete before continuing, set the object's DISTRIBUTE
and REPLY
attributes. Using these attributes, notification occurs when a modification has completed in all caches. When Attributes.REPLY
is set for an object, replies are sent back to the modifying cache when the modification has been completed at the remote site. These replies are returned asynchronously; that is, the CacheAccess.replace()
and CacheAccess.invalidate()
methods do not block. Use the CacheAccess.waitForResponse()
method to wait for replies and block.
To use Object Caching Service for Java's highest level of consistency set the appropriate attributes on the region, subregion, group, or object to make objects act as synchronized objects.
On a region, subregion, or group, setting Attributes.SYNCHRONIZE_DEFAULT
sets the SYNCHRONIZE
attribute for all of the objects within the region, subregion, or group.
On an object, setting Attributes.SYNCHRONIZE
forces applications to obtain ownership of the object before the object can be loaded or modified. Setting this attribute effectively serializes write access to objects. To obtain ownership of an object, use the CacheAccess.getOwnership()
method. Using the Attributes.SYNCHRONIZE
attribute, notification is sent to the owner when the update is completed. Use CacheAccess.releaseOwnership()
to block until any outstanding updates have completed, and the replies are received. This releases ownership of the object so that other caches can update or load the object.
When using this level of consistency, with Attributes.SYNCHRONIZE
, the CacheLoader.load()
method should call CacheLoader.netSearch()
before loading the object from an external source. Calling CacheLoader.netSearch()
in the load method tells the Object Caching Service for Java to search all other caches for a copy of the object. This prevents different versions of the object from being loaded into the cache from an external source.
|
Copyright © 2001 Oracle Corporation. All Rights Reserved. |
|