Cache Invalidation Listener

The Dynamic Cache provides following types of listeners

Invalidation Listener



The Invalidation Listener receive InvalidationEvents (defined in the com.ibm.websphere.cache package) when entries from the cache are removed, due to an explicit user invalidation, timeout, least recently used (LRU) eviction, cache clear, or disk timeout. Applications can immediately recalculate the invalidated data and prime the cache before the next user request.

Ex. In most of the database applications, whenever you retrieve a record from database you can cache it or when user creates a new record instead of directly creating it in database you can create cached entry for it. You keep updating/modifying this record. And when application server is about wipe this record out from memory it will call your invalidation listener at that point you can write that record into database.

This is how you create an InvalidationListener

public class MyInvalidationListener implements InvalidationListener {

public void fireEvent(InvalidationEvent invalidationEvent) {
System.out.println("Entering MyInvalidationListener.fireEvent()");
System.out.println("Cache Name " +invalidationEvent.getCacheName());
System.out.println("Cache ID " +invalidationEvent.getId());
System.out.println("Cache Value " +invalidationEvent.getValue());
System.out.println("Exiting MyInvalidationListener.fireEvent()");
}

}

As you can see i am just printing the invalidated entry into system.out
Then you attach it to your Distributed map using this code

distributedMap= (DistributedMap)context.lookup("wpcertification/cache/customCache");
System.out.println("Distributed Map " + distributedMap);
distributedMap.enableListener(true);
distributedMap.addInvalidationListener(new MyInvalidationListener());


When you get distributedMap from JNDI first you set enableListener to true and then create object of your listener and attach it to the distributed map.

In order to test the invalidation listener, i went to cache monitor application and i did click on the invalidate button next to the entry that i want to invalidate.



WHen the entry was invalidated this is the output that i see in my SystemOut.log

invalidating id: timeofCache
Entering MyInvalidationListener.fireEvent()
Cache Name wpcertification/cache/customCache
Cache ID timeofCache
Cache Value 16:38:16
Exiting MyInvalidationListener.fireEvent()


As you can see i am getting sufficient data to post this cached entry into database.

You can download the modified version of CustomDynaCache portlet to try this listener

Change Entry Listener



If you want you can also attach an listener that gets called every time the cached entry is modified.


public class MyChangeListener implements ChangeListener{

public void cacheEntryChanged(ChangeEvent changeEvent) {
System.out.println("Entering MyChangeListener.cacheEntryChanged()");
System.out.println("Cache Name " +changeEvent.getCacheName());
System.out.println("Cache ID " +changeEvent.getId());
System.out.println("Cache Value " +changeEvent.getValue());
System.out.println("Exiting MyChangeListener.cacheEntryChanged()");

}

}


Then attach the Change event listener to the distributedMap like this

distributedMap= (DistributedMap)context.lookup("wpcertification/cache/customCache");
distributedMap.addChangeListener(new MyChangeListener());


Now when you update the cached entry you should see messages like this in SYstemOut.log

Entering MyChangeListener.cacheEntryChanged()
Cache Name wpcertification/cache/customCache
Cache ID timeofCache
Cache Value 17:16:20
Exiting MyChangeListener.cacheEntryChanged()

1 comment:

Anonymous said...

Hello Sunil

Thanks for the post! This really helps with no real examples from IBM.

One Suggestion

Need to add

distributedMap.enableListener(true);

for change listener also, otherwise it will not work.

You can add the above line to the change listener code to avoid confusion