Search code examples
javajbossejbmemcachedspymemcached

What kind of bean should I use to provide access to a pool of objects in EJB?


At a high level, I have a MemcachedPoolService class that has two methods: getClientInstance() and returnClientInstance(client). As expected, getClientInstance() returns an instance of a MemcachedClient (spymemcachced) to the caller, and returnClientInstance(client) returns a MemcachedClient back to the pool. MemcachedPoolService needs to be available to other @Stateless services (injected) that all need access to Memcached.

Currently I have MemcachedPoolService marked as a @Singleton, but I'm getting the following error when more than one client tries accessing the app:

[0m[31m16:54:22,968 ERROR [org.jboss.as.ejb3.invocation] (http-/0.0.0.0:8080-10) 
 JBAS014134: EJB Invocation failed on component MemcachedPoolService for method public
 net.spy.memcached.MemcachedClient com.apexlab.cache.MemcachedPoolService.getClientInstance():
 javax.ejb.EJBTransactionRolledbackException: JBAS014373: EJB 3.1 PFD2 4.8.5.5.1 concurrent
 access timeout on org.jboss.invocation.InterceptorContext$Invocation@24bf375e - could not 
 obtain lock within 5000MILLISECONDS

What would be the best way to set up my MemcachedPoolService (and my web app in general) for a production environment to avoid getting the concurrent timeout exceptions?


Solution

  • First and foremost, MemcachedPoolService is a stateless service, and hence if you are not doing any db updates that require consistency (Thats why it is @Singleton anyway, otherwise you would use @Stateless), then simply mark the class as

    @Singleton
    @Lock(LockType.READ)
    public class MemcachedPoolService{}
    

    or

    @Singleton
    public class MemcachedPoolService{
    
      @Lock(LockType.READ)
      public void myPossibleMultiAccessMethod(){}
    }
    

    if thats not an option, then:

    @Singleton
    public class MemcachedPoolService{
    
      @AccessTimeout(Integer.MORE_THAN_5000_MILLIS)
      public void myPossibleMultiAccessMethod(){}
    }