-
1. Re: Singleton EJBs not working as expected
sfcoy Oct 15, 2012 8:08 AM (in response to mylos78)The lock semantics are applied to the bean instance, not the method call.
The spec (§4.8.5.1) says (emphasis mine):
If the container invokes a method associated with a Read lock, any number of other concurrent invocations on Read methods are allowed to access the bean instance simultaneously.
That *could* be interpreted to mean "calls of other methods". If you had another getter method that is also marked with @Lock(READ), then it should be allowed to proceed.
I'm not sure if that is what's happening though. It would be interesting to get some comments from the implementor.
-
2. Re: Singleton EJBs not working as expected
jaikiran Oct 15, 2012 8:42 AM (in response to sfcoy)It doesn't matter which method is being called as long as it is a READ and there's no WRITE in progress. We have testcase here for Singleton concurrency semantics https://github.com/jbossas/jboss-as/blob/master/testsuite/integration/basic/src/test/java/org/jboss/as/test/integration/ejb/singleton/concurrency/SingletonBeanTestCase.java
Mylos, what exact issue are you running into?
I suspect that you might be using the "new()" keyword to instantiate a EJB instead of using either JNDI lookup or injection. Is that right?
-
3. Re: Singleton EJBs not working as expected
mylos78 Oct 15, 2012 9:18 AM (in response to jaikiran)Hello Jaikiran,
thanks for your reply. No the EJB is instantiated in a Servlet using:
@EJB SimpleSingleton singleton;
My concern is that, since the get method will contain as well access to EIS, I'm afraid that it can become an application bottleneck, if it allows just one client until the method is returned.
This is the full EJB singleton code ( Using Thread.sleep() to simulate access to EIS)
import static javax.ejb.LockType.*;
import javax.ejb.Lock;
import javax.ejb.Singleton;
import javax.ejb.Startup;
import org.jboss.logging.Logger;
import java.util.*;
@Singleton
@Startup
public class SimpleSingleton {
private HashMap cache;
private static final Logger logger =
Logger.getLogger(SimpleSingleton.class);
@PostConstruct
public void initCache(){
this.cache = new HashMap();
}
@Lock(READ)
public Object get(String name) {
logger.info("Getting data");
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return cache.get(name);
}
@Lock(WRITE)
public void set(String name, Object value) {
cache.put(name, value);
}
}
Now if I invoke the EJB from a Servlet, the singleton.get(key) won't allow concurrent access to this method.
@EJB SimpleSingleton singleton;
. . . . .
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String key = request.getParameter("key");
String value = request.getParameter("value");
singleton.set(key, value);
// NO CONCURRENT ACCESS TO THIS METHOD
String retVal = (String)singleton.get(key);
}
Hope somebody can shed some light on it....
Thanks
Mylos
-
4. Re: Singleton EJBs not working as expected
jaikiran Oct 15, 2012 9:25 AM (in response to mylos78)Are you sure it's the READ which isn't allowed. Your servlet invocation also has a WRITE in the same method (doGet) which will block for multiple requests and a READ too will block as a result. If you really want to test to see if multiple simultaneous reads are allowed, then you have to leave out the write from the equation.
-
5. Re: Singleton EJBs not working as expected
mylos78 Oct 15, 2012 10:09 AM (in response to jaikiran)Hello,
yes I've tested as well removing the call to the put method which has WRITE lock.
I'm attaching the Project test case (it's just an Eclipse project made up of an EJB and a Servlet). You will see that by issuing multiple Servlet requests:
http://localhost:8080/SingletonExample/SingletonClient
Just one, at the time, is allowed to enter the get method:
16:02:15,206 INFO [ejb.SimpleSingleton] (http--127.0.0.1-8080-1) Getting data
. . . . . wait 10 secs
16:02:25,206 INFO [ejb.SimpleSingleton] (http--127.0.0.1-8080-1) Getting data
Thanks for your time
Mylos
-
SingletonExample.zip 4.8 KB
-
-
6. Re: Singleton EJBs not working as expected
jaikiran Oct 15, 2012 10:20 AM (in response to mylos78)How are you triggering that servlet client? From that log, it looks like there aren't multiple threads involved.
-
7. Re: Singleton EJBs not working as expected
mylos78 Oct 15, 2012 11:35 AM (in response to jaikiran)Yes, true sorry I didn't pay attention to it. Now I have tested using JMeter and it produces the correct behaviour:
17:30:55,563 INFO [ejb.SimpleSingleton] (http--127.0.0.1-8280-1) Getting data
17:30:58,014 INFO [ejb.SimpleSingleton] (http--127.0.0.1-8280-2) Getting data [no wait time]
17:31:04,398 INFO [ejb.SimpleSingleton] (http--127.0.0.1-8280-3) Getting data [no wait time]
. . . . .
I don't know why if I issue several HTTP calls from the *same* browser, using multiple Tabs, then calls are enqueued using always the same thread. I guess it's a matter of Servlet Session...maybe the Web server detects that calls are coming from the same Session.......
Thanks for your help
-
8. Re: Singleton EJBs not working as expected
wolfc Oct 15, 2012 3:10 PM (in response to mylos78)@Lock(READ)
or@Lock(WRITE)
have nothing to do with the state changes you are enacting in your bean.It only has to do with the level of concurrency. It ensures that there are either multiple readers or 1 writer (thread) on your bean.