Is EJB 3 The Solution For The "Multicore Crisis"? (@Stateless and @Stateful)
During yesterday's excellent talk of Heinz Kabutz at Jazoon, it turned out, that even the += operator isn't atomic and can cause problems in parallel, multicore, multiprocessor platforms. It doesn't have to be super-parallel - just current commodity hardware can already cause the problems - and you have to synchronized your code (without synchronized :-)).
Nevertheless, because EJB (1.0, 1.1, 2.0, 2.1, 3.0 and probably 3.1) are always executed in a dedicated thread - they appear as single threaded for the developer. For every thread (=user request, transaction) a new EJB instance is created (or reused from pool) - there is actually no shared state, except you access singletons, files etc. - which is not allowed. Actually the spec even prohibits the usage of the synchronization primitives and threading functionality inside EJBs.
Furthermore the programming model is rather procedural (or if you will "service oriented") - so in the @Stateless Session Beans the methods process some input data and give it back to the caller. Even the @Stateful Session Beans do not brake the rule - the container still prohibits concurrent access to the @Stateful instance. Because a @Stateful Session Bean can be only executed in a single thread - you do not have (you shouldn't!) care about the threading either.
The best of all: if you acess the JPA-persistence - the container synchronizes the data for you. Every transaction receives a copy of the JPA-entity (it is often implemented in this way), so nothing bad can happen even in this case.
I'm not sure whether there are actually some corner cases - where EJB programming model breaks in multicore environment (except you are violating the spec). Every EJB-instance can be only executed in a single thread. And every thread is (hopefully) executed in a single core. So if you keep the transactions short, and do not "hack" the EJBs accessing static variables or singletons - you are on the bright side :-).
I agree with that. For quite a while EJBs were sold as a solution to get at least :-) the concurrency issues right (well, among other things of course) but at the same time we had to pay for that with the complexity of the EJB technology itself (EJB 1.0 to EJB2.1). Now with EJB 3.x there is much less complexity in developing EJB apps which is very appealing!
Regarding concurrent acess to SFSB: as you said, you must not call them concurrently (regardless of how you are trying to provoke this) or the container will through a RemoteException. So even vendor specific "optimizations" that we see sometimes, such as "allow-concurrent-calls" for Weblogic, will only block the second caller until the first one is finished.
Apart from performance maybe, multicores shouldn't be much different from the appserver's perspective than SMPs. So IMHO multicores will not break the EJB programming model. Better go and double check your servlet code :-)
Posted by Frank on June 27, 2008 at 01:40 PM CEST #
Reducing or getting rid of concurrency difficulties is for me on of the biggest advantages of JEE. Maybe not big enough to warrant EJB 2.1, but with EJB 3 and tools like JBoss Seam, it's great to have a simple (well, at least more simple that than before EJB 3 and Seam. Software development is rarely simple) and powerful platform to use. And it's fun again.
Posted by Markus Jais on June 27, 2008 at 02:57 PM CEST #
Standard request/response applications are easy if you look at concurrency control. EJB is simple, but it can be just as simple with other frameworks because everything is isolated and for isolation you don't need much complexity.
As soon as you don't have a simple request/response situation (batch processing for example) EJB is terrible. You need add complex solutions (like JMS) for simple stuff (like processing a request asynchronously). Even though a blockingqueue with an executor would be more than sufficient. That is where EJB really shows its age and limitations.
Posted by Peter Veentjer on October 06, 2008 at 01:13 PM CEST #
Ps: JPA is not going to help you with concurrency problems in any way. You still need to do concurrency control. In most cases you need to pick the correct isolation level (most developers find this an issue) or do custom locking. JPA provides a littlebit support for this with the Lockmodes, but it depends on the OR-mapper/dialect how well this is supported. So to use JPA correct, you really need to know what you are doing. JPA = not magic that protects you against these issues.
And in a few years the number of cores is going to outnumber the number of concurrent users. This means that we have to do concurrency on a lower level than the request/response level. With EJB 3 this is going to be a serious challenge.
Posted by Peter Veentjer on October 06, 2008 at 01:14 PM CEST #