To design a cached result set using a session bean

Discussions

EJB design: To design a cached result set using a session bean

  1. Hi
    I want to design a cached result set(Using a static ResultSet variable), in a session bean. My actual problem goes like this.
    There are n number of Applets accesing a session bean , for a particular ResultSet. There is a get method in the bean which returns a static ResultSet declared and defined in the bean itself. The static ResultSet is refreshed every 2 minutes and shared accross by all instances of the Session Bean.
    Now the problem is to refresh that ResultSet in the Session Bean every 2 mins. Since using threads is not advised in EJB's what do you think should be te strategy for refreshing the static ResultSet in the Session Bean?
    I have choosen the concept of using EJB's to design a ResultSet Cache to take advantage of Pooling and other facilities provided to EJBs by the container.. Do you think this approach is correct in the first place to implement a Cached ResultSet ?
  2. When you refer to static result set, are you talking about a global result set accessed by all applets, ie in the "application" context. If that's the case, we don't need several session beans to maintain the same data. Maybe I am missing your requirement, please clarify...
  3. Yes, in fact I was referring to the several instances of the same session bean sharing the same data globally.
  4. First off, don't use the ResultSet itself to cache data. Keeping the ResultSet in memory will also keep an open database connection, which would be bad. Instead, copy your data from the ResultSet into something else (e.g. a HashMap).

    Other than that, I suggest you lazy-reload the data by rechecking the current system time whenever the session bean does a lookup. Something like this:

    public class DataCache {
      private static final DataCache SINGLETON = new DataCache();
      private static final long CACHE_TIME = 2 * 60 * 1000;

      public static DataCache() getInstance() {
        return SINGLETON;
      }

      private Map data = null;
      private long lastUpdate = 0;

      public synchronized Map getData() {
        long currentTime = System.currentTimeMillis();
        if ((currentTime - lastUpdate) > CACHE_TIME) {
          lastUpdate = currentTime;
          this.data = loadData();
        }
        return this.data;
      }

      private Map loadData() {
        // Load data via JDBC;
      }
    }

    In your session bean:

    DataCache.getInstance().getData();

    You might be able to play with the synchronization to get better performance (e.g. only synchronize during updates), but the logic gets a lot messier.
  5. Sun also has a JDBC Rowset implementation you can use. It has the same method as ResultSet but do not require database connection. You can wrap this object in a cache to prevent building extra data structures.Download it from here http://java.sun.com/products/jdbc/download.html