|
Caching is extensively used for optimizing database applications
and effectively reducing traffic between the database and the application.
ColdFusion ORM supports two levels of caching:
Session level
Secondary level
Session level cacheObjects that are loaded from the database are always cached
in the ORM Session as long as the session is open. When EntityLoad is
called to retrieve an object in a session for the first time, ORM
fetches the data from the database and constructs the object. In
any subsequent call to load the same object in the same session,
ORM fetches the object from the session cache. To forcefully retrieve
the object from the database, EntityReload should
be called on the object.
For more details on ORM Sessions and its lifecycle, see ORM session management and Architecture.
Secondary level cacheColdFusion provides the ability to store the data that
is retrieved from the database in secondary cache. The contents
in secondary cache live longer than the life-time of a session.
It can also be the life-time of the process or in-definite (disk-caching),
depending on the ability of the secondary cache provider. The cache
can also be used in a distributed environment depending on the ability
of the secondary cache provider.
An important difference between session level cache and secondary
level cache is that the session level caches the whole object but
the secondary level caches only the data.
Secondary level cache can be leveraged by using an external cache
provider with ColdFusion ORM. EHCache, JBossCache, OSCache, SwarmCache,
and Tangosol Coherence Cache are some popular secondary cache providers,
which can be plugged into Hibernate.
ColdFusion uses EHCache as the default secondary cache provider.
EHCache is a distributed caching solution that supports memory and
disk-based caching. EHCache can be configured using a configuration
file. Different cache regions can be defined in the configuration
file. Each cache region has its own configuration that specifies
details including the number of elements it can store, eviction
policy, time to live (ttl), and idle time.
ehcache.xml is available in the following location: CF_root\lib\.
For details of the properties in the ehcache.xml, refer to the documentation
available at the following URL:
http://ehcache.org/
The following is a sample EHCache configuration file (ehcache.xml):
<ehcache>
<diskStore path="java.io.tmpdir"/>
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU"
/>
<cache name="Artist"
maxElementsInMemory="20"
eternal="true"
overflowToDisk="false"
/>
</ehcache>
Modifications to ehcache.xml in ColdFusion 9.0.1ehCache.xml
includes the following configuration properties:
diskSpoolBufferSizeMB: Size to allocate
the DiskStore for a spool buffer.
The default size is 30
MB. Each spool buffer is used only by its cache.
Turning on
trace-level logging shows if backup for cache created/updated using action="put" occurs
in the diskstore.
clearOnFlush: Determines if the MemoryStore
must be cleared when the cache is flushed. By default, the MemoryStore
is cleared.
diskExpiryThreadIntervalSeconds: The number
of seconds between runs of the disk expiry thread. The default value
is 120 seconds.
Note: The functions cacheGetProperties and cacheSetProperties can be
used to get/set these properties.
Use secondary cacheTo use secondary cache, you must configure the following
settings in the application:
ormsettings.secondarycacheenabled
This
setting defines whether the secondary cache would be used by the
application. By default, this is set to false.
ormsettings.Cacheprovider
This setting
defines the cache provider that needs to be used for secondary cache.
This defaults to EHCache. The other values for this setting are
JBossCache, OSCache, SwarmCache and Hashtable. You can also specify
the fully qualified class name of the cache provider.
ormsettings.cacheconfig
This setting
defines the configuration file required by the secondary cache provider.
For example, EHCache requires EHCache.xml that
defines the configuration settings for the secondary cache. Specify
the path to the XML file in this setting. If this setting is not
defined, cache provider uses its default configuration.
After you have configured the secondary cache, it is critical
to identify the objects in your application that can be cached because
the data cached by secondary cache is shared by all the sessions
of an application. Typically, caching should be enabled for a CFC
that represents:
For each type of object that needs to be cached, you also need
to decide the access strategies. ORM provides the following cache
strategies that you can use for your objects:
read-only
This strategy is useful for data that
is read frequently but never updated. This is the best performing
cache strategy.
nonstrict-read-write
This strategy is useful for data
that is updated occasionally. Typically, it is very unlikely that
two transactions would update the same object simultaneously.
read-write
This strategy may be appropriate if your
data needs to be updated. It carries more overhead than the two
preceding strategies.
Transactional
This strategy provides the support for
transactional cache. It can only be used if the cache provider is
transaction aware.
Support for these strategies depend on the cache provider. Not
all the cache providers support all the cache strategies. For more
information on these strategies, see:
www.hibernate.org/hib_docs/reference/en/html/performance-cache.html
The secondary cache can cache the following types of data.
Cache data of a persistent objectIn this case, the data of the persistent object is cached.
It will not cache the associations or associated object's data.
To enable this flag on a persistent CFC, specify the following attributes
on the component.
cacheuse: Defines the caching strategy.
cachename: Defines the name of the cache
region to be used by the secondary cache provider. If you do not
specify a region name for the component, the entity name of the
component is considered as the cache name. In case a region is not
specified in the configuration file, a region is automatically created
with the default configuration.
For example:
<cfcomponent persistent="true" schema="APP" table="Artists" cachename="artist" cacheuse="read-only">
Cache the association data of a persistent objectIn this case, the primary key of the associated objects
are cached. It does not cache the objects loaded as part of the
association unless caching is enabled for those objects. To cache
an association, specify the following attributes on the association
property.
cacheuse: Defines the caching strategy.
cachename: Defines the name of the cache
region to be used by the secondary cache provider. If you do not
specify a region name for the association property, the <comoponent_name>.<property_name>
is considered as the cache name. In case a region is not specified
in the configuration file, a region is automatically created with
the default configuration.
For example:
<cfproperty name="art" fieldtype="one-to-many" cfc="CArt" fkcolumn="ArtID" cachename="ArtistArts" cacheuse="read-only">
Cache query dataIn this case, the results of queries that are executed
by ORMExecuteQuery() or EntityLoad() methods
are cached in the secondary cache. To enable caching query data,
pass "cacheable=true" and "cachename='cachename' values
in the options struct of the methods. If you do not specify the cachename,
the query is cached in the default query cache. It is recommended
that you to specify the cachename so that you can control
eviction.
For example:
availableArts = ORMExecuteQuery("from CArt where issold=0", {}, false, {cacheable=true, cachename="availableArtsQuery"});
Secondary cache example using EHCacheStep 1: Set the following in Application.cfc:
<cfset this.name="Caching_Example">
<cfset this.datasource="cfartgallery">
<cfset this.ormenabled="true">
<cfset this.ormsettings.secondarycacheEnabled=true>
<cfset this.ormsettings.cacheProvider= "ehcache">
<cfset this.ormsettings.cacheConfig="ehcache.xml">
Step 2: Define the cache settings in the CFCs.
CArtist.cfc
<cfcomponent persistent="true" schema="APP" table="Artists" cachename="artist" cacheuse="read-only">
<cfproperty name="artistid" fieldtype="id"/>
<cfproperty name="firstname"/>
<cfproperty name="lastname"/>
<cfproperty name="state"/>
<cfproperty name="art" fieldtype="one-to-many" cfc="CArt" fkcolumn="ArtID" cachename="ArtistArts" cacheuse="read-only">
</cfcomponent>
CArt.cfc
<cfcomponent persistent="true" schema="APP" table="Art">
<cfproperty name="artid" generator="identity" fieldtype="id"/>
<cfproperty name="artname"/>
<cfproperty name="issold"/>
</cfcomponent>
Step 3:
<cfscript>
//This will cache the Artist Component and also the association. It wouldn't cache the Art objects.
artistObj = EntityLoad("CArtists", 3, true);
//This will cache the query.
availableArts = ORMExecuteQuery("from CArt where issold=0", {}, false, {cacheable=true, cachename="availableArtsCache"});
</cfscript>
Evict content from secondary cacheColdFusion provides the following methods to evict contents
from the secondary cache.
ORMEvictEntity("<component_name>", [primarykey])
This method is used to evict items for the given component name,
from the secondary cache. If the primary key is specified, then
the data of the entity with that primary key is evicted. Primary
key should be a value in case of simple primary key or should be
a struct in case of composite primary key.
Example:
<cfset ORMEvictEntity("CArtists")>
Evicts all the cache data of CArtist entity.
<cfset ORMEvictEntity("CArtists", 1)>
Evicts the cache data of CArtists entity whose primary key is
1.
ORMEvictCollection("<component_name>", "<collection_name>", [primarykey])
This method is used to evict all the collection/association data
for the given component name and collection name, from the secondary
cache. If the primary key is specified, then, the collection or
association data of the entity with the primary key is evicted.
Example:
<cfset ORMEvictCollection("CArtists", "art")>
Evicts all the association or collection data of collection art
belonging to the component CArtists.
<cfset ORMEvictCollection("CArtists", "art", 1)>
Evict the association or collection data of collection art belonging
to the component CArtists with primary key 1.
ORMEvictQueries([cachename])
This method is used to evict the data of all the queries from
the default query cache. If cache name is specified, then, the data
of all the queries belonging to the cache region with the given
cache name are evicted. Example:
<cfset ORMEvictQueries()>
Evicts the data of all the queries from the default query cache.
<cfset ORMEvictQueries("availableArtsCache")>
Evicts the data of all the queries from the cache region with
the name availableArtsCache.
Support for user-defined caches in ColdFusion 9.0.1Except in cacheSetProperties and cacheGetProperties, user-defined
caches are supported in all caching functions.
Edit ehCache.xml (cfroot/lib)to set the properties for
user-defined caches as shown in the following example:
<!--- item to put in user-defined cache --->
<cfset currentTime = Now()>
<!--- put item in user-defined cache --->
<cfset timeToLive=createtimespan(0,0,0,30)>
<cfset timeToIdle=createtimespan(0,0,0,30)>
<cfset customCache = "usercache">
<cfset id = "cache1">
<cfset cachePut(id,currentTime,timeToLive,timeToIdle,customCache)>
<!-- list items in the cache --->
List Items in cache:
<cfset cacheIds = cacheGetAllIds(customCache)>
<cfdump var="#cacheIds#"><br>
<!--- print cache data --->
<cfset cachedData = cacheGet(id,customCache)>
<cfoutput>#cachedData#</cfoutput>
<!--- print cache metadata --->
Cache metadata:
<cfset mdata = cacheGetMetadata(id,"object",customCache)>
<cfdump var="#mdata#">
<!--- clear user-defined cache --->
<cfset cacheRemove(ArrayToList(cacheIds),true,customCache)>
|
|
|