Chapter 4 EJB CMP Tuning
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:
In summary, the best use case for caching is data that is static. If the data changes often, the overhead of updating caches can outweigh the performance benefits of caching. If the data is updated too frequently, soft locking or hard locking may yield better performance. Furthermore, the data consistency requirements dictate how cached data can be used. Decide how much consistency you require, then optimize within those constraints.
Cache synchronization can be enabled to minimize the occurrences of transaction rollback due to overlapping updates. EAServer supports cache synchronization between servers in a cluster and from the database to EAServer. In some cases, the overhead of synchronization may outweigh the benefits incurred.
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.
For components, object caching is enabled if you have configured an isolation level that requires caching. You can further customize the caching parameters as described in "Configuring object caching". 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.
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 If your application requires read consistency, choose an isolation
level that requires it, such as read_committed_verify_updates
or read_committed_with_cache_verify_updates
.
See "Configuring CMP isolation level".
When read consistency is required, caching should be used only when
the data changes infrequently. Caching volatile data can make your
application perform worse because the added overhead of retrying queries
that roll back because the data changed.
Update consistency When using caching, transactional update consistency is ensured by:
verify
in
the name. At commit time, the verification query checks whether
the data has changed since it was originally selected. You should not
disable OCC when using object caching, and you should use a timestamp
column rather than using the default value-comparison technique
of concurrency control. For details on configuring the timestamp
column, see "Configuring OCC options".
Read consistency using timeouts and synchronization For applications that have a more lax requirement for read consistency, you can configure cache timeouts and synchronization to minimize the use of stale data. The cache timeout sets a time limit on how long cached data remains valid. Stale entries are refreshed from the source database before the data is used in the component. You can also configure your database to notify the cache manager of updates, inserts, and deletes. Doing so allows EAServer to refresh the cache contents after data is modified by another application. 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 can configure inter-server synchronization, which uses the EAServer message service to replicate data changes between servers in the cluster. This ensures that all caches have the same data. To use this option, configure the Cache Synchronization property described in "Configuring 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:
CtsComponents/ObjectCache
| Syntax | To indicate |
|---|---|
nMor nm |
n megabytes, for
example:
512M |
nKor nk |
n kilobytes, for
example:
1024K |
n |
n bytes, for example:
536870912 |
sync
property;
the inherited setting can be overridden by setting the component
property.
| Option | Explanation |
|---|---|
| None | (The default.) Indicates no synchronization is performed. This value is appropriate if the component is not deployed in a cluster, you have configured a component isolation level, or the cache timeout provides adequate read consistency for transactions. |
| Mirror | Replication without transactional consistency. This value is appropriate for entity components that maintain transient data (that is, the data is not saved to persistent database). If you use this option, you must configure mirror pairs for your cluster as described in "Cluster configuration for in-memory failover" in the EAServer Programmer's Guide. |
| Replicate | Replication with transactional consistency. For updates, the complete instance state is replicated between servers. |
| Invalidate | Replication with transactional consistency.
For updates, the instance state is not replicated. Rather, updates
are propagated by refreshing the cache entry from the remote database.
This value may yield better performance than the replicate
option
if:
In this case, the overhead of replicating instance state may exceed that of refreshing each cache from the database. |
Cache synchronization requires a working message service
If using object caching in a cluster, make sure the EAServer
message service is configured and running on each server. The cache
manager uses the message service for cache synchronization between
servers. Chapter 8, "Setting
up the Message Service," in the EAServer
System Administration Guide describes how to run the
message service.
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:
com.sybase.jaguar.objectcache.size=size-value com.sybase.jaguar.objectcache.timeout=timeout-value com.sybase.jaguar.objectcache.sync=sync-method
| Named cache property | Component property |
|---|---|
com.sybase.jaguar.objectcache.size
|
Cache Size. If not specified, the default is unlimited. |
com.sybase.jaguar.objectcache.
|
Cache Timeout. If not specified, the default is infinity. |
com.sybase.jaguar.objectcache.sync
|
Cache Synchronization |
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 4-5, with each parameter separated from the next by white space, for example:
[default][cache size=1M timeout=10]
| 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 "Configuring 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:
|
timeout=seconds
|
The cache timeout in seconds. A value of 0 indicates infinity. |
verify
|
Specifies that finder results must be verified at the end of the transaction. Restrictions apply—see "Verifying cached finder method results" for more information. |
ignore insert
|
If database change notification is enabled, inserts do not invalidate the cache. |
ignore delete
|
If database change notification is enabled, deletes do not invalidate the cache. |
ignore update
|
If database change notification is enabled, updates do not invalidate the cache. |
Verifying cached finder method results To obtain verified finder method semantics, include the keyword verify
in
the cache settings for the finder query. For example, use [cache
verify]
in place of [cache]
.
For components using object caching, this setting specifies that
any finder method data used from cache should be verified at commit
time with an appropriate database query. The verification query
runs with an isolation level that is equivalent to higher than the
component isolation level. Query cache verification requires the
use of a table-level timestamp, and all tables referenced in the
SQL query must use the same table timestamp as the entity bean for
which the finder method is defined.
EAServer uses the transaction local cache to minimize the number of database reads required when finder methods are called in a transaction. For example, if a finder method returns 100 rows, the worst case requires 101 queries to retrieve the data for each row. The transaction local cache helps achieve the ideal of selecting all required data at the beginning of the transaction.
The transaction local cache is enabled automatically if finder queries return enough data to populate the cache. In other words, the finder query returns all rows in the table. The default query properties do this. If you have modified them, verify that they return all rows. For more information, see "Specifying finder- and ejbSelect-method queries" in Chapter 27, "Creating Entity Components," in the EAServer Programmer's Guide.
You can set the component property com.sybase.jaguar.component.tlc.sort to specify whether EAServer sorts entries before calling ejbStore. Setting this property to true helps to avoid deadlock when separate transactions concurrently update multiple instances of the same component. The default of false may provide better performance by eliminating the sorting step. You cannot enable sorting unless the primary key class implements the java.lang.Comparable interface. Most java.lang utility classes implement this interface, such as String, Integer and so forth.
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:
Enabling database change notification
com.sybase.jaguar.server.services
to include
the Message Service and Database Notify components, for example:
CtsComponents/MessageService,CtsComponents/DatabaseNotify
dn.caches=SybaseCache,OracleCache
cms.cache
property
will be used.
sp_notify={call my_own_notify_proc ?,?}
{call sp_notify ?,?}
For Oracle databases, a sample script is provided in the the file DatabaseNotify_Oracle.sql in the Repository/Component/CtsComponents subdirectory of your EAServer installation. The sample script below 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
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 (C) 2004. Sybase Inc. All rights reserved. |
| |