Caching contents on WC is not only a cachespec.xml configuration task.
Another powerful feature is to cache database query results using Websphere Commerce data cache.
There are two ways to cache database query results: using cachespec.xml or configuring specified DistributedMap instances.
Probably you already know how to cache those contents caching the related commands.
For example if you want to cache the catalog entry data you need to add to your cachespec this cache entry
<cache-entry>
<class>command</class>
<sharing-policy>not-shared</sharing-policy>
<name>com.ibm.commerce.catalog.objsrc.CatalogEntryCache</name>
<property name="persist-to-disk">false</property>
<cache-id>
<component type="method" id="getFinderName">
<required>true</required>
</component>
<component type="method" id="getFinderArgs">
</component>
<component type="method" id="getContextInfo">
<required>false</required>
</component>
<priority>4</priority>
<timeout>172800</timeout>
<inactivity>900</inactivity>
</cache-id>
</cache-entry>
simply copying it from the samples files on WCD (<WCDFolder>\samples\dynacache\cachespec.xml).
But you can also use “specified DistributedMap instances”. I put it between quotes because is not so documented on infocenter.
First of all what are the “specified DistributedMap instances”?
The default list is here but how should I activate these instances?
This is the tricky part: you have to create an object cache instance using WAS console (on WC 7) or adding a cacheinstances.properties file to your Stores.war\WEB-INF\classes folder (on WC 6).
In theory this process is documented on Commerce infocenter but something on the WAS configuration part is missing.
Suppose you want to cache the catalog entry query results using DistributedMap and not with command caching.
What you have to do first is to find the default DistributedMap we are referring to.
Using the same example above, we find the DistributedMap associated to the com.ibm.commerce.catalog.objsrc.CatalogEntryCache command is “WCCatalogEntryDistributedMapCache”.
Then we create it in WAS console
This is enough to WC to start using it to cache database query results.
If we ask Madisons home page and we open the Cache monitor, we already see the com.ibm.commerce.catalog.objsrc.CatalogEntryCache entries in the corresponding DistributedMap instance
Now you can configure the object instance behaviour in Commerce adding a tag to the Commerce instance file.
The tag is the “CrossTransactionCache” and, in our example, you can add this
<CrossTransactionCache enabled="true" commandCaching="default" maxInactivityTime="86400" maxTimeToLive="172800" defaultResultSizeThreshold="8" clearUserOnLogoff="true" clearUserDataCacheOnLogoff="false" maxInvalidationIdsPerTransaction="100000" clearCacheOnMaxInvalidationIdsPerTransaction="false" reduceMemory="false" reduceInvalidationIds="false"> <WCCatalogEntryDistributedMapCache enabled="true" reduceMemory="false" maxTimeToLive="172800" maxInactivityTime="86400"/> </CrossTransactionCache>
to refine the configuration.
Don’t forget the most important part: the invalidation.
As you saw in the cache monitor screenshot, every entry has a default TTL of 172800 seconds.
The best way (and the default) to invalidate these entries is to use the database triggers.
You can find the default database triggers on WCD samples folder (<WCDFolder>\schema\db2\wcs.cacheivl.trigger.sql).
In our example the trigger we have to apply is
CREATE TRIGGER civu_c21_modified
AFTER UPDATE ON CATENTRY
REFERENCING NEW AS trow
FOR EACH ROW MODE DB2SQL
INSERT INTO cacheivl (dataid) VALUES('WCT+CATENTRY+CATENTRY_ID:%:'
|| RTRIM(CHAR(trow.CATENTRY_ID))
)
;
to create an invalidation row in CACHEIVL every time there is a modification on a specific record in the CATENTRY table.
I slightly modified the original “civu_c21″ trigger to match one of the invalidation ids associated to our entries
WCT+CATENTRY+CATENTRY_ID:%:10185 WCT+CATENTRY+? WCT+CATENTRY+CATENTRY_ID:? WCT+?
The default scheduled DynacacheInvalidationCmd will do the invalidation work for us.

