Administer > Dynamic caching > Cache invalidation
Write commands for command-based invalidation
In order to allow a command call be intercepted by the dynamic cache, the command must be written to the WebSphere Command Framework with its implementation class extending from CacheableCommandImpl (in the com.ibm.websphere.command package).
To simplify command writing for command-based invalidation, WebSphere Commerce has updated the abstract classes, ControllerCommandImpl and TaskCommandImpl to extend from CacheableCommandImpl so that any commands extend from these abstract classes would also extend from CacheableCommandImpl and therefore be eligible for command-based invalidation.
When writing such commands, it is also important to know what the invalidation IDs are going to be, and understand the invalidation rules that intercepts calls to the commands. Since invalidation IDs are generated based on methods and fields present in the command as input parameters, all the methods required to construct the invalidation IDs, should be provided in the command interface and be implemented.
An example of using command invalidation in WebSphere Commerce
The following example shows how WebSphere Commerce uses command invalidation. When the command DeleteMemberGroupMemberCmdImpl which deletes a particular member belonging to a particular member group is executed successfully, the dynamic cache will invalidate the cache-entry defined in the invalidation rule. In this example, it is defined as " DC_userId: userId " where userId is the value being returned from the getMemberId method. For example, DC_userId:-1000, DC_userId:-1001, and so on. This command has a get method, getMemberId(), that retrieves the user ID that is being deleted and this method is used in computing which cache entries with a dependency ID based on a user ID gets deleted. The same logic applies for the command AddMemberGroupMemberCmdImpl which also has a get method, getMemberId():
<cache-entry> <class>command</class> <name>com.ibm.commerce.membergroup.commands.AddMemberGroupMemberCmdImpl</name> <name>com.ibm.commerce.membergroup.commands.DeleteMemberGroupMemberCmdImpl</name> <invalidation>DC_userId <component type="method"id="getMemberId"> <required>true</required> </component> </invalidation> </cache-entry>
All the preceding invalidation rules are shipped with WebSphere Commerce in the sample cache policy. You can find more sample invalidation rules in the WebSphere Commerce installation directory under the /samples/dynacache/invalidation subdirectory. See the README file entitled "Sample invalidation cache policies for Dynacache" for more information about incorporating the invalidation rules into the cachespec.xml file.
Cache invalidation example
The following example shows how to set up caching policies in the cachespec.xml file to cache the ProductDisplay JSP page for the Consumer Direct business model in WebSphere Commerce and how to invalidate the cache entry by defining the invalidation rules in the same XML file. The example defines multiple dependency IDs along with the cache ID generation rule for the JSP file. Each dependency ID is used to invalidate the cache entry when the cache entry is updated under different circumstances. This example only shows a subset of policies required to invalidate the CachedProductDisplay JSP. For a complete example and detailed information, see the README file in the WC_INSTALL/samples/dynacache/invalidation directory.
<cache> <cache-entry> <class>servlet</class> <name>/ConsumerDirect/ShoppingArea/CatalogSection/CatalogEntrySubsection/CachedProductDisplay.jsp</name> <property name="save-attributes">false</property> <!-- Cache ProductDisplay.jsp --> <cache-id> <component id="storeId" type="parameter"> <required>true</required> </component> <component id="catalogId" type="parameter"> <required>true</required> </component> <component id="productId" type="parameter"> <required>true</required> </component> <component id="DC_lang" type="attribute"> <required>true</required> </component> <component id="DC_curr" type="attribute"> <required>true</required> </component> <component id="DC_porg" type="attribute"> <required>true</required> </component> <component id="DC_cont" type="attribute"> <required>true</required> </component> <component id="DC_mg" type="attribute"> <required>true</required> </component> </cache-id> <!-- Used for invalidating the product display cache entry --> <!-- that belongs to a specific store --> <dependency-id>storeId <component id="storeId" type="parameter"> <required>true</required> </component> </dependency-id> <!-- Used for invalidating the cache entry of a specific product --> <dependency-id>productId <component id="productId" type="parameter"> <required>true</required> </component> </dependency-id> <!-- Used for invalidating the product display cache entry --> <!-- that belongs to a specific catalog in the store --> <dependency-id>storeId:catalogId <component id="storeId" type="parameter"> <required>true</required> </component> <component id="catalogId" type="parameter"> <required>true</required> </component> </dependency-id> <!-- Used for invalidating the product display cache entry --> <!-- that is under a specific contract --> <dependency-id>contractId <component id="DC_cont0" type="attribute"> <required>true</required> </component> </dependency-id> </cache-entry> <cache-entry> <class>command</class> <sharing-policy>not-shared</sharing-policy> <name>com.ibm.commerce.catalogmanagement.commands.AddCatalogDescCmdImpl</name> <name>com.ibm.commerce.catalogmanagement.commands.UpdateCatalogDescCmdImpl</name> <!-- ********************************************************* --> <!-- Invalidate all the product page cache entries that --> <!-- might be affected when the catalog description is changed --> <!-- ********************************************************* --> <invalidation>storeId:catalogId <component id="getStoreId" type="method"> <required>true</required> </component> <component id="getCatalogId" type="method"> <required>true</required> </component> </invalidation> </cache-entry> <cache-entry> <class>command</class> <sharing-policy>not-shared</sharing-policy> <name>com.ibm.commerce.catalogmanagement.commands.ListpriceAddCmdImpl</name> <name>com.ibm.commerce.catalogmanagement.commands.ListpriceDeleteCmdImpl</name> <name>com.ibm.commerce.catalogmanagement.commands.ListpriceUpdateCmdImpl</name> <name>com.ibm.commerce.catalogmanagement.commands.OfferAddCmdImpl</name> <name>com.ibm.commerce.catalogmanagement.commands.OfferDeleteCmdImpl</name> <name>com.ibm.commerce.catalogmanagement.commands.OfferUpdateCmdImpl</name> <name>com.ibm.commerce.catalogmanagement.commands.ProductAttributeUpdateCmdImpl</name> <name>com.ibm.commerce.catalogmanagement.commands.AttributeValueUpdateCmdImpl</name> <name>com.ibm.commerce.catalogmanagement.commands.AddListpriceCmdImpl</name> <name>com.ibm.commerce.catalogmanagement.commands.DeleteListpriceCmdImpl</name> <name>com.ibm.commerce.catalogmanagement.commands.UpdateListpriceCmdImpl</name> <name>com.ibm.commerce.catalogmanagement.commands.AddOfferCmdImpl</name> <name>com.ibm.commerce.catalogmanagement.commands.DeleteOfferCmdImpl</name> <name>com.ibm.commerce.catalogmanagement.commands.UpdateOfferCmdImpl</name> <name>com.ibm.commerce.catalogmanagement.commands.UpdateAttributeCmdImpl</name> <name>com.ibm.commerce.catalogmanagement.commands.UpdateAttributeValueCmdImpl</name> <!-- ********************************************************* --> <!-- Invalidate the specific product page cache entry when the --> <!-- product is updated --> <!-- ********************************************************* --> <invalidation>productId <component id="getCatentryId" type="method"> <required>true</required> </component> </invalidation> </cache-entry> <cache-entry> <class>command</class> <sharing-policy>not-shared</sharing-policy> <name>com.ibm.commerce.contract.commands.ContractSuspendCmdImpl</name> <name>com.ibm.commerce.contract.commands.ContractTCDeployCmdImpl</name> <!-- ********************************************************* --> <!-- Invalidate all the product page cache entries under a --> <!-- specific contract --> <!-- ********************************************************* --> <invalidation>contractId <component id="getContractId" type="method"> <required>true</required> </component> </invalidation> </cache-entry> <cache-entry> <class>command</class> <name>com.ibm.commerce.tools.devtools.store.commands.StoreProfileUpdateCmdImpl</name> <name>com.ibm.commerce.tools.devtools.flexflow.ui.commands.impl.FlexflowUpdateCmdImpl</name> <name>com.ibm.commerce.store.commands.StoreOpenCmdImpl</name> <name>com.ibm.commerce.store.commands.StoreCloseCmdImpl</name> <!-- ********************************************************* --> <!-- Invalidate all the product page cache entries that --> <!-- belong to the store when the store is updated --> <!-- ********************************************************* --> <invalidation>storeId <component id="getStoreId" type="method"> <required>true</required> </component> </invalidation> </cache-entry> <cache-entry> <class>command</class> <sharing-policy>not-shared</sharing-policy> <name>com.ibm.commerce.catalogimport.commands.CatalogImportJobAddCmd</name> <!-- ********************************************************* --> <!-- Invalidate all the product page cache entries that --> <!-- belong to the store when the store catalog is updated --> <!-- ********************************************************* --> <invalidation>storeId <component id="getStoreId" type="method"> <required>true</required> </component> </invalidation> </cache-entry> </cache>