Oracle Application Server TopLink Application Developer's Guide 10g (9.0.4) Part Number B10313-01 |
|
A cache is a repository that stores recently used objects for an application. Holding objects in the cache helps you minimize database access, and improves application performance.
Oracle Application Server TopLink uses two object caches: the session cache maintains objects retrieved from and written to the database; and the Unit of Work cache holds objects while they participate in transactions. These caches maintain objects based on class and primary key values.
This chapter explores cache use, and discusses the following topics:
The cache is a key OracleAS TopLink component. You use the cache to improve application performance and manage user access to the database. This section introduces concepts that help you optimize the way your application uses its caches.
The session cache and the Unit of Work cache work together with the database connection to manage objects in an OracleAS TopLink application. The object life cycle relies on these three mechanisms.
The session cache is a shared cache that services clients attached to a given database session. When you read data from or write data to the database, OracleAS TopLink saves a copy in the session cache and provides that data to all other processes in the session.
OracleAS TopLink adds objects to the cache from:
You can configure queries to search the cache for existing data.If the data exist in the cache, rather than perform a database read, OracleAS TopLink returns the cached data.
For more information about query cache usage, see "In-Memory Query Cache Usage".
The Unit of Work cache services operations within the Unit of Work. It maintains and isolates objects, and writes changed or new objects to the session cache after the Unit of Work commits changes to the database.
Stale data is an artifact of caching in which an object is not the most recent version. To avoid stale data, implement an appropriate cache locking strategy.
Cache locking regulates when processes read or write an object. Depending on how you configure it, cache locking determines whether a process can read or write an object that is in use with another process. Cache locking also enables you to manage stale data issues.
When you deploy your OracleAS TopLink application in a cluster, the cluster generally includes several caches. Because each cache services a different application, this raises the possibility that changes from one application may not appear in the other applications in the cluster.
Distributed cache synchronization reduces the occurrence of stale data across the caches in the system. When an object changes in one cache, distributed cache synchronization enables you to update the other caches in the cluster to replace stale data.
For more information about distributed cache synchronization, see "Distributed Cache Synchronization".
An OracleAS TopLink cluster is a collection of servers that:
Discovery occurs when servers in a cluster learn of other servers in the cluster. Discovery uses a multicast protocol to monitor sessions as they join and leave the OracleAS TopLink cluster.
A message transport is the messaging protocol servers in a cluster use to send and receive messages. OracleAS TopLink uses a transport protocol to exchange object updates between cooperating sessions.
A name service enables you to search for objects on remote caches. OracleAS TopLink cache synchronization uses a name service when it looks up connections to other sessions in the OracleAS TopLink cluster.
If you use RMI as a transport, the RMI Registry provides lookup capabilities. In most other cases, the Java Naming and Directory Interface (JNDI) provides lookup functionality.
The propagation mode determines when a client regains control after it propagates object changes. OracleAS TopLink supports synchronous and asynchronous propagation modes.
When you propagate updates synchronously, OracleAS TopLink prevents the committing client from performing other tasks until the remote merge process is complete.
In asynchronous mode, OracleAS TopLink creates separate threads to propagate changes to remote servers. OracleAS TopLink returns control to the client immediately after the local commit, whether or not the changes merge successfully on the remote servers. This offers superior performance for applications that are somewhat tolerant of stale data.
By default, OracleAS TopLink optimizes concurrency to minimize cache locking during reads or writes. Use the default OracleAS TopLink isolation level unless you have a very specific reason to change it.
Use the following application programming interface (API) on Databaselogin
to change the OracleAS TopLink isolation level:
login.setCacheTransactionIsolation(int cacheTransactionIsolation
)
The available settings for cacheTransactionIsolation
are:
ConcurrentReadWrite
: the default; it allows concurrent object read and write
SynchronizedWrite
: allows only a single Unit of Work to merge into the cache at once
SynchronizedReadOnWrite
: does not allow reading or other Unit of Work merge while a Unit of Work is merging
A well-managed cache makes your application more efficient. There are very few cases in which you turn the cache off entirely, as the cache reduces database access, and is an important part of managing object identity.
To make the most of your cache strategy and to minimize your application's exposure to stale data, we recommend the following:
If other applications can modify the data used by a particular class, use a weaker style of cache for the class. For example, the SoftCacheWeakIdentityMap
or WeakIdentityMap
minimizes the length of time the cache maintains a de-referenced object.
For more information about configuring cache usage on a per-class basis, see "Working with Identity Maps" in the Oracle Application Server TopLink Mapping Workbench User's Guide.
Any query can include a flag that forces a cache refresh to the database.
For more information about configuring cache refresh on a per-query basis, see "Refresh".
The need to maintain up-to-date data for all applications is a key design challenge for building a distributed application environment. The difficulty of this increases as the number of servers within an environment increases. OracleAS TopLink provides a distributed cache synchronization feature that ensures data in applications remains current.
Cache synchronization in no way eliminates the need for an effective locking policy. However, it does reduce the number of optimistic lock exceptions encountered in a distributed architecture, and decreases the number of failed or repeated transactions in an application.
OracleAS TopLink provides cache synchronization at the session level. This ensures that object updates associated with a given session propagate to the caches on all other servers in the cluster.
This section describes:
Because each application server approaches caching differently, you must configure cache synchronization to work effectively within the distributed system.
For more information about choosing cache configuration options, see the application server or J2EE container documentation.
To enable and configure cache synchronization in the sessions.xml
file, specify the cache-synchronization-manager element, and configure the required sub-elements.
Example 8-1 illustrates how to configure cache synchronization in the sessions.xml
file for a session that:
<cache-synchronization-manager> <clustering-service> oracle.toplink.remote.rmi.RMIJNDIClusteringService </clustering-service> <jndi-user-name>userName</jndi-user-name> <jndi-password>password</jndi-password> <naming-service-initial-context-factory-name> oracle.com.evermind.server.rmi.RMIInitialContextFactory </naming-service-initial-context-factory-name> <naming-service-url>ormi://hostname:23791/appName</naming-service-url> </cache-synchronization-manager>
The configuration in Example 8-1 includes the name, password, context factory class, and URL. Oracle Application Server Containers for J2EE requires all four sub-elements to enable name lookup on remote hosts. Other servers require different values for the context factory and URL.
For Oracle Application Server Containers for J2EE, the URL element includes the ormi://
protocol, the local host name and RMI server port, and the name of the application in which the OracleAS TopLink session is deployed.
The clustering-service
element specifies the name service and transport combination used to communicate changes. Choose the combination that works best with your application. Your choices are:
oracle.toplink.remote.rmi.RMIJNDIClusteringService
: uses JNDI to look up remote sessions, and RMI point-to-point connections to propagate changes between sessions.
oracle.toplink.remote.rmi.RMIClusteringService
: uses RMIRegistry to look up sessions, and RMI point-to-point connections to propagate changes between sessions.
oracle.toplink.remote.ejb.EJBJNDIClusteringService
: uses JNDI to look up session beans that propagate changes between sessions.
oracle.toplink.remote.corba.CORBAJNDIClusteringService
: uses JNDI to look up sessions, and CORBA point-to-point connections to propagate changes between sessions.
oracle.toplink.remote.corba.JMSClusteringService
: uses JNDI to look up Java Message Service (JMS) topics that propagate changes between sessions.
<cache-synchronization-manager> <clustering-service> oracle.toplink.remote.rmi.RMIJNDIClusteringService </clustering-service> ... </cache-synchronization-manager>
Discovery occurs when servers in a cluster learn of other servers in the cluster and uses a multicast protocol to monitor sessions as they join and leave the OracleAS TopLink cluster. If you are running OracleAS TopLink with other Oracle Application Server 10g components, ensure the port you select does not conflict with other components. If OracleAS TopLink's default discovery configuration conflicts with settings for other services on the same host, you can override the discovery settings.
You can configure discovery to use specific optional multicast socket options, including:
multicast-port
: overrides the default multicast port used for discovery (default is 6018)
multicast-group-address
: overrides the default multicast group used for discovery (default is 226.18.6.18)
packet-time-to-live
: overrides the default time-to-live (TTL) setting for discovery multicast socket (default is 2)
<cache-synchronization-manager> <clustering-service> ... </clustering-service> <multicast-port>6020</multicast-port> <multicast-group-address>228.1.2.3</multicast-group-address> <packet-time-to-live>3</packet-time-to-live> ... </cache-synchronization-manager>
A name service enables you to search for objects on remote caches. JNDI provides the name service for most applications, and offers the following optional elements to customize JNDI support in your application:
jndi-user-name
: user name value assigned to Context.SECURITY_PRINCIPAL
property when looking up names in JNDI
jndi-password
: password value assigned to Context.SECURITY_CREDENTIALS
property when looking up names in JNDI
naming-service-initial-context-factory-name
: the class used when creating initial context instances to use for looking up in JNDI
naming-service-url
- the URL to use when looking up through the naming service (value assigned to Context.PROVIDER_URL
property in JNDI)
Not all servers require all four optional elements.
<cache-synchronization-manager> <clustering-service> ... </clustering-service> <naming-service-initial-context-factory-name> weblogic.jndi.WLInitialContextFactory </naming-service-initial-context-factory-name> <naming-service-url>t3://hostName:7001</naming-service-url> </cache-synchronization-manager>
The JMS API is a protocol for communication that provides asynchronous communication between components in a distributed computing environment. Because OracleAS TopLink integrates with the JMS publish/subscribe mechanism, use JMS to improve the scalability of your cache synchronization.
For more information about the JMS API, see the JMS specification at
http://java.sun.com/products/jms
You must configure a JMS service in the environment before OracleAS TopLink can leverage the service. To enable the service:
sessions.xml
file to use the factory and topic names.
For more information on how to complete steps 1, 2, and 4, see the JMS service provider documentation.
For more information on how to complete step 3, see "Configuring JMS in sessions.xml".
Example 8-5 illustrates a jms.xml
configuration file for Oracle Application Server Containers for J2EE. Note that the host and port of the topic connection factory is the host and port of the JMS server hosting the topic, and not the host or port of the local JMS server.
<jms-server port="9128"> <topic name="MyCacheSyncTopic" location="jms/MyCacheSyncTopic"/> <topic-connection-factory host="micky" port="9127" name="Cache Sync Topic Factory" location="jms/MyTopicFactory" password="password" username="admin"/> <log> <file path="../log/jms.log"/> </log> </jms-server>
To configure JMS in the sessions.xml
file, use the following optional elements:
jms-topic-connection-factory-name
: the JNDI name to use when looking up the connection factory for the JMS topic
jms-topic-name
: the JNDI name to use when looking up the JMS topic.
<cache-synchronization-manager> <clustering-service> oracle.toplink.remote.jms.JMSClusteringService </clustering-service> <jms-topic-connection-factory-name> jms/MyTopicFactory </jms-topic-connection-factory-name> <jms-topic-name>jms/MyCacheSyncTopic</jms-topic-name> ... </cache-synchronization-manager>
Note that JMS neither requires nor makes use of discovery.
When you use JMS in Oracle Application Server Containers for J2EE, set the naming service URL to the hostname of the JMS server hosting the topic. Example 8-7 illustrates this for an OracleAS TopLink session running in Oracle Application Server Containers for J2EE using JMS.
<cache-synchronization-manager> <clustering-service> oracle.toplink.remote.jms.JMSClusteringService </clustering-service> <jndi-user-name>admin</jndi-user-name> <jndi-password>password</jndi-password> <jms-topic-connection-factory-name> jms/MyTopicFactory </jms-topic-connection-factory-name> <jms-topic-name>jms/MyCacheSyncTopic</jms-topic-name> <naming-service-initial-context-factory-name> oracle.com.evermind.server.rmi.RMIInitialContextFactory </naming-service-initial-context-factory-name> <naming-service-url>ormi://micky</naming-service-url> </cache-synchronization-manager>
The Cache Synchronization Manager enables you to specify the propagation mode for your OracleAS TopLink application:
The optional is-asynchronous
element controls the propagation mode, regardless of the transport used. By default, propagation occurs asynchronously.
<cache-synchronization-manager> <clustering-service>...</clustering-service> <is-asynchronous>false</is-asynchronous> ... </cache-synchronization-manager>
You can define error handlers to respond to raised exceptions. The should-remove-connection-on-error element (an optional sub-element of cache-synchronization-manager) specifies whether a connection to another session is discarded if an error occurs while sending an update. By default, OracleAS TopLink discards connections when errors occur.
<cache-synchronization-manager> <clustering-service>...</clustering-service> <should-remove-connection-on-error>false</should-remove-connection-on-error> ... </cache-synchronization-manager>
Some distributed systems require only a small number of objects to be consistent across the servers in the system. Conversely, other systems require that several specific objects must always be guaranteed to be up-to-date, regardless of the cost. If you build such a system, you can explicitly refresh selected objects from the database at appropriate intervals without incurring the full cost of distributed cache synchronization.
To implement this type of strategy:
When you execute a query, if the required objects are in the cache, OracleAS TopLink returns the cached objects without checking the database for a more recent version. This reduces the number of objects that OracleAS TopLink must build from database results, and is optimal for non-clustered environments. However, this may not always be the best strategy for a clustered environment.
To override this behavior, set a refresh policy that specifies that the objects from the database always take precedence over objects in the cache. This updates the cached objects with the data from the database.
You can implement this type of refresh policy on each OracleAS TopLink descriptor, or just on certain queries, depending upon the nature of the application.
For more information about setting the refresh policy for a descriptor, see "Setting Descriptor Information," in the Oracle Application Server TopLink Mapping Workbench User's Guide.
For more information about setting the refresh policy for a query, see "Refresh".
Note: Refreshing does not prevent phantom reads from occurring. See "Refreshing Finder Results". |
When you invoke a findByPrimaryKey
finder, if the object exists in the cache, OracleAS TopLink returns that copy. This is the default behavior, regardless of the refresh policy. To force a database query, you can configure the query to refresh by setting refreshIdentityMapResult()
on it.
For more information about caching options, see "Caching Options".
The Remote Command Manager (RCM) enables OracleAS TopLink to send synchronization messages across the network to non-OracleAS TopLink applications. This feature is separate from the standard cache synchronization feature.
When you build a distributed system that includes both OracleAS TopLink and non-OracleAS TopLink applications, use the RCM in place of regular cache synchronization. Do not use RCM and regular OracleAS TopLink cache synchronization concurrently.
This section discusses the RCM, and offers information on:
To enable RCM in a distributed system, enable RCM for all OracleAS TopLink sessions in the system. In addition, non-OracleAS TopLink applications must meet the following criteria to participate in cache synchronization through the RCM:
toplink.jar
must be included in the application class path.
The RCM is both modular and pluggable. Figure 8-2 illustrates the components of the RCM.
RCM components include:
The CommandManager
is the central point of control for the system.
The DiscoveryManager
dynamically maintains the membership of the OracleAS TopLink cluster.
The TransportManager
manages the transport level of the message exchange.
The CommandProcessor
interface sits between the RCM and the application. It is the main integration point for non-OracleAS TopLink applications.
An implementation of the CommandConverter
translates commands between OracleAS TopLink and non-OracleAS TopLink applications. Regular OracleAS TopLink sessions do not require a CommandConverter
implementation, because they do not require conversion.
The process of initiating and transmitting commands from an OracleAS TopLink application is as follows:
getCommandManager()
accessor on the session to obtain a CommandManager
interface.
CommandManager.propagateCommand(command)
method to initiate commands from the OracleAS TopLink session. Pass the command to be remotely executed as the command
argument.
TransportManager
transmits the command to other members of the cluster.
To send remote commands to the cluster, non-OracleAS TopLink applications invoke the CommandManager.propagateCommand(command)
method. The application must provide a CommandConverter
interface to convert the application-specific command format to an OracleAS TopLink Command object.
Likewise, when a non-OracleAS TopLink application receives an OracleAS TopLink command, it must implement a converter to translate the command for the CommandManager
. To execute the command, a non-OracleAS TopLink application invokes the processCommand(command) method.
The RCM passes remote commands along virtual channels. The RCM assigns each subscribing service a channel on which to send and receive commands, and all services assigned to a particular channel send (or publish) commands to that channel. Services also act as subscribers to their assigned channel, receiving all the commands published to that channel by other services.
You can assign any number of channels in the system without performance penalty, but any given service may only publish and subscribe to a single channel. You cannot reassign channels dynamically, or while discovery is active.
If you do not set a channel name, RCM assigns a default channel when you add services to the cluster. For example, if you do not set a channel name for any service instance you add to the system, all services subscribe to the same, default channel.
Use the RCM API to configure the RCM. For OracleAS TopLink applications, create the cluster as part of the session initialization (for example: use a session PreLogin
event when the session is initialized from the sessions.xml
file). Note that neither the OracleAS TopLink Sessions Editor nor the sessions.xml
file directly support RCM configuration.
The logical OracleAS TopLink cluster includes any number of OracleAS TopLink session-based applications, and non-OracleAS TopLink applications. Bind non-OracleAS TopLink applications in with OracleAS TopLink code to enable them to access the OracleAS TopLink commands.
To configure applications that use OracleAS TopLink sessions for RCM:
CommandManager
interface. Pass the session as the CommandProcessor
argument.
For example:
CommandManager rcm = new RemoteCommandManager(session);
session.setShouldPropagateChanges(true);
rcm.setUrl("ormi://myHostname:23791/myDeployedApplication");
For a WebLogic Server, the URL can appear as follows:
rcm.setUrl("t3://myHostname:7001");
For example:
rcm.getTransportManager().setUserName("admin"); rcm.getTransportManager().setPassword("password");
For example:
rcm.getTransportManager().setRemoteContextProperties(
new java.util.Hashtable());
DiscoveryManager
parameters to custom multicast socket settings for your environment.
For example:
rcm.getDiscoveryManager().setMulticastGroupAddress("226.1.2.3"); rcm.getDiscoveryManager().setMulticastPort(3122);
For example:
rcm.setChannel("MyChannel");
For example:
rcm.setShouldPropagateAsynchronously(false); rcm.setShouldRemoveConnectionOnError(true);
CommandManager rcm = new RemoteCommandManager(session); rcm.setUrl("ormi://ferengi:23791/orderEntryApp"); rcm.getTransportManager().setUserName("admin"); rcm.getTransportManager().setPassword("password"); session.setShouldPropagateChanges(true);
CommandManager rcm = new RemoteCommandManager(session); rcm.setUrl("t3://ferengi:7001"); rcm.getTransportManager().setRemoteContextProperties( new java.util.Hashtable()); session.setShouldPropagateChanges(true);
To configure RCM on applications that do not use the OracleAS TopLink sessions:
CommandProcessor
interface.
For example:
CommandProcessor processor = new ApplicationCommandProcessor();
CommandManager
interface. Pass the session as the CommandProcessor
argument:
CommandManager rcm = new RemoteCommandManager(processor);
CommandConverter
interface and set an instance of the implementation class on the CommandManager
.
For example:
CommandConverter converter = new ApplicationCommandConverter(); rcm.setCommandConverter(converter);
For example:
rcm.getTransportManager().setRemoteContextProperties(
new java.util.Hashtable());
DiscoveryManager
parameters to custom multicast socket settings for your environment.
For example:
rcm.getDiscoveryManager().setMulticastGroupAddress("226.1.2.3"); rcm.getDiscoveryManager().setMulticastPort(3122);
For example:
rcm.setChannel("MyChannel");
For example:
rcm.setShouldPropagateAsynchronously(false); rcm.setShouldRemoveConnectionOnError(true);
rcm.initialize();
CommandManager rcm = new RemoteCommandManager( new ApplicationCommandProcessor()); rcm.setCommandConverter( new ApplicationCommandConverter()); rcm.setUrl("ormi://ferengi:23791/orderEntryApp"); rcm.getTransportManager().setUserName("admin"); rcm.getTransportManager().setPassword("password"); rcm.initialize();
CommandManager rcm = new RemoteCommandManager( new ApplicationCommandProcessor()); rcm.setCommandConverter( new ApplicationCommandConverter()); rcm.setUrl("t3://ferengi:7001"); rcm.getTransportManager().setRemoteContextProperties( new java.util.Hashtable()); rcm.initialize();
Propagated commands often execute on multiple subscribing services. The subscribing services only return results to the publishing server if the command fails. The propagation mode affects error handling when a subscribing node reports a failure:
RemoteCommandException
on the publishing service. The publishing service stops command propagation.
RemoteCommandException
on the publishing service. Because the threads are asynchronous to the publishing server's thread, the exceptions are not raised within the context of the calling thread.
You can choose to catch and handle exceptions explicitly. The CommandProcessor
interface includes the handleException()
method for this purpose. Implement this method to catch exceptions thrown from a remote command service. For OracleAS TopLink applications, you can specify an exception handler on the session to handle the exception.
Raised exceptions are either:
CommunicationException
: thrown when a transport-level communications error occurs
RemoteCommandException
: thrown when any other problem occurs.
When you use RCM, consider the following:
-userThreads
command line option when you start the server. This enables the DiscoveryManager
to initialize as a separate thread.
CommandProcessor
interface must initiate its own transactions, and provide clean-up functionality in the case of failure.
CommandProcessor
interface to an RCM. Do not use other types of sessions.
To create additional custom commands, extend the oracle.toplink.remotecommand.Command
class, and implement the executeWithSession(Session)
method. If the CommandProcessor
interface is an OracleAS TopLink session, this method executes when the service executes.
You can pass instances of these commands to the propagateCommand()
method, and publish them for execution on the remote services.
|
Copyright © 2000, 2003 Oracle Corporation. All Rights Reserved. |
|