Chapter 25 Managing Persistent Component State


Entity object and query caching

EAServer supports object and query caching for EJB entity beans and entity components that use automatic persistence. Caching can improve performance by minimizing the number of database select queries required for ejbLoad operations, finder method invocations, and ejbSelect method invocations. Most database applications are governed by the 80:20 rule: 80% of users access 20% of the data. Object caching increases performance and scalability by allowing faster access to the most recently used data.

Assuming that the database access is the principal bottleneck, the expected performance gain falls in these ranges, depending on the ratio of update to read-only transactions:

Besides the transaction mix, the actual performance gain depends on:

Note   Read-only methods When using automatic persistence, the persistence engine detects read-only method invocations. You do not need to set the Read Only method property.

Cache architecture

Object and query caching place an in-memory cache and a cache manager component in between component instances and the associated database. You can configure the object cache and cache manager used by each entity component. You can configure the query cache used by each finder and ejbSelect method. You can configure caches that are dedicated to a single component or query method or shared by multiple components and query methods.

The cache manager is a component that implements the CtsComponents::ObjectCache IDL interface. EAServer provides a built in component, CtsComponents/ObjectCache, which is a high-performance C++ implementation of this interface. You can provide custom implementations that implement this interface. The cache manager must be coded in C++ or Java, and the Instances/Bind Object property must be enabled for the component. Ideally, cache managers should be coded in C++ to avoid the overhead of Java garbage collection.

Object caching must be configured for each component, as described in "Enabling object caching". Object caching is disabled by default.

Query caching must be configured for each finder and ejbSelect method, on the Persistence/Query Mapping subtab in the Component Properties dialog box. See "Enabling query caching". Query caching is disabled by default.

Cache coherency and transaction consistency

When data is maintained in the object cache as well as the source database, you must take steps to ensure these transactional constraints are satisfied:

Read consistency Unless database change notification is enabled, transactional read consistency requires that EAServer have exclusive write access to the database tables for your entity components. You can configure your database to notify the cache manager of updates, inserts, and deletes. See "Enabling database change notification" for more information. The same notification technique is used for both object caching and query caching.

In addition, if the component is deployed in a cluster, you must take steps to ensure that row changes are propagated to the object caches for each server in the cluster. This can be achieved with two approaches:

Update consistency Transactional update consistency is ensured by:

Enabling object caching

For each entity component that uses automatic persistence, enable object caching on the Persistence/Object Cache subtab in the Component Properties dialog box. The settings are:

Steps Creating a named cache

If you want a cache to be shared by multiple components, finder methods or ejbSelect methods, you must create a named cache as follows:

  1. If the Repository/Component/ObjectCache directory does not exist under your EAServer installation, create it.
  2. Create a text file in the Repository/Component/ObjectCache directory named Cache.props, where Cache is the cache name used in component properties.
  3. Add lines as shown below to configure the cache properties. All properties are optional. If not set, the default values apply:
    com.sybase.jaguar.objectcache.size=size-value
    com.sybase.jaguar.objectcache.timeout=timeout-value
    com.sybase.jaguar.objectcache.sync=sync-method
    


    These values correspond to the component object caching properties, as described in the table below. Each cache property uses the same value syntax as the corresponding component property:
    Named cache property Component property
    com.sybase.jaguar.objectcache.size Cache Size.
    com.sybase.jaguar.objectcache.
    timeout
    Cache Timeout
    com.sybase.jaguar.objectcache.sync Cache Synchronization

Enabling query caching

Query caching allows EAServer to cache the values returned by finder and ejbSelect method queries. When caching is enabled for a query, the key values returned by each invocation are cached in memory, with the method input parameter values serving as the cache key. Together with entity object caching, query caching can reduce the number of unnecessary database reads.

To enable caching for a finder or ejbSelect query, append [cache] to the end of the Query Mapping property value that corresponds to the method. For example:

[default][cache]

Or, for a query mapped to an EJB-QL query:

ejbQuery:[cache]

You can specify optional parameters with this syntax:

[cache cache-params]

Where cache-params is a list of parameters listed in Table 25-9, with each parameter separated from the next by white space, for example:

[default][cache size=1M timeout=10]

Table 25-9: Query cache configuration parameters
Parameter To indicate
name=name The cache name. Specifying a named cache allows multiple queries to use one cache. The named cache must be created and configured as described for named object caches in "Enabling object caching".

Only one of name or size may be specified.
size=size The cache size. Only one of name or size may be specified. The value syntax is:
  • nM or nm to specify a size in Megabytes, for example: 1M
  • nK or nk to specify a size in kilobytes, for example: 512k
  • n to specify a size in bytes, for example: 1048576
timeout=seconds The cache timeout in seconds. A value of 0 indicates infinity.
ignore insert If database change notification is enabled, inserts do not invalidate the cache.
ignore delete If database change notification is enabled, updates do not invalidate the cache.
ignore update If database change notification is enabled, updates do not invalidate the cache.

Enabling database change notification

This feature allows the use of database triggers to notify EAServer's entity object cache of changes to the underlying table rows. The notification mechanism works as follows:

  1. Database triggers call a stored procedure sp_publish to publish a message for each SQL insert, update or delete.
  2. sp_publish "publishes" the messages by placing them in a table cms_notify.
  3. A cluster-wide singleton service, CtsComponents/DatabaseNotify, pulls notification messages from the cms_notify table using stored procedure sp_notify. These messages are then published to the EAServer message service. The expected latency for message delivery (from trigger to cache entry removal) is approximately one second at most.
  4. The storage component (when using CtsComponents/JdbcStorage) listens for messages on selected topics, parses the messages for key fields, and notifies the Object Cache to remove the relevant entries.

Steps Enabling database change notification

  1. Install the required stored procedures in the target database(s). See "Sample script for database stored procedures".
  2. In the Jaguar Manager properties for your server, use the All Properties tab to configure the property com.sybase.jaguar.server.services to include the Message Service and Database Notify components, for example:
    CtsComponents/MessageService,CtsComponents/DatabaseNotify
    


    If you have never run the message service in your installation, see the EAServer System Administration Guide for initial message service configuration instructions. Database change notification requires a working message service.
  3. Optionally add an entry to MessageServiceConfig.props to specify the name(s) of connection caches for databases which need to be monitored for notification messages. These connection caches must have type JDBC, for example:
    dn.caches=SybaseCache,OracleCache
    


    By default, the cache referenced by the cms.cache property will be used.
  4. Optionally add an entry to MessageServiceConfig.props to specify the JDBC callable statement (or prepared statement) to be used to pull change notification messages from the database, for example:
    sp_notify={call my_own_notify_proc ?,?}
    


    By default, the callable statement is:
    {call sp_notify ?,?}
    
  5. For each entity component that is to be configured for database notification, enable the Create Database Triggers option on the Persistence/General subtab in the Component Properties dialog box. This option requests automatic creation of triggers.
  6. Optionally change the message service topic names associated with database tables. The default topic name is the unqualified table name. You must change the topic name if multiple databases contain tables with the same name. To change the topic name associated with a table, set the table mapping property for the table's notify operation, as described on "Configure table-mapping properties".

Sample script for database stored procedures

This sample script is for Sybase Adaptive Server Enterprise. Modifications are required for use on other databases:

use master
go

if not exists (select name from sysdatabases where name = "notifydb")
  begin
    create database notifydb
    exec sp_dboption notifydb, "trunc log on chkpt", "true"
  end
go

use notifydb
go

checkpoint
go

if not exists (select 1 from sysobjects where name="cms_notify" and type="U")
  begin
    create table cms_notify
    (
      id numeric(16,0) identity primary key,
      type char(1) not null,
      name varchar(100) not null,
      message varchar(255) not null,
      options varchar(255) not null
    )
  end
go

if not exists (select 1 from sysusers where name="guest")
  exec sp_adduser guest
go

use sybsystemprocs
go

if exists (select 1 from sysobjects where name="sp_notify" and type="P")
  drop proc sp_notify
go

create proc sp_notify
  (@from numeric(16,0),
  @last numeric(16,0))
as
  if @from <= @last
    delete from notifydb..cms_notify where id >= @from and id <= @last
  declare @loop int
  select @loop = 1
  while @loop <= 60
    begin
      declare @rows int
      select @rows = count(*) from notifydb..cms_notify
      if @rows > 0
        begin
          set rowcount 100
          select id, type, name, message, options
            from notifydb..cms_notify
            order by id
          return
        end
      waitfor delay "00:00:01"
      select @loop = @loop + 1
    end
go

sp_procxmode sp_notify, anymode
go

grant execute on sp_notify to public
go

if exists (select 1 from sysobjects where name="sp_publish" and type="P")
  drop proc sp_publish
go

create proc sp_publish
  (@topic varchar(255),
  @message varchar(255),
  @options varchar(255))
as
  insert into notifydb..cms_notify (type, name, message, options)
    values ("T", @topic, @message, @options)
go

sp_procxmode sp_publish, anymode
go

grant execute on sp_publish to public
go

if exists (select 1 from sysobjects where name="sp_send" and type="P")
  drop proc sp_send
go

create proc sp_send
  (@topic varchar(255),
  @message varchar(255),
  @options varchar(255))
as
  insert into notifydb..cms_notify (type, name, message, options)
    values ("Q", @topic, @message, @options)
go

sp_procxmode sp_send, anymode
go

grant execute on sp_send to public
go


Customizing the implementation

The storage component responds to any suitably formatted messages that are published to the configured topic names for each mapped table. You can provide you own implementation of the stored procedures or the notification component.

To publish a change message, the Message Service 'text' property should be "insert", "delete" or "update", each key column should have a corresponding property (unless multiple rows were affected in which case key columns should be omitted). If using the Java Message Service (JMS) to publish the messages, use a TextMessage and use header properties for the key column values.

 


Copyright © 2002 Sybase, Inc. All rights reserved.