ejb thread safety: do we need it? - java

Consider a stateless EJB
from ejb 3.1 spec
containers will support many instances of a session
bean executing concurrently; however, each instance sees only a
serialized sequence of method calls. Therefore, a stateful or
stateless session bean does not have to be coded as reentrant
So a Stateless seession bean can "serve" at most one request at a time,
this is usually implemented by the container managing a pool of beans.
The great goal of all this is Thread safety.
My question is why do we need this form of thread safety ?
I mean Spring beans are singleton and not thread safe (they can serve any number of request at a time) and we have no problem with that.

You need that form of thread safety if the stateless session bean has member variables that are themselves not thread safe (e.g., a SAXParser). However, since stateless session beans don't have client affinity like stateful session beans, the use cases are admittedly relatively rare, and the servlet programming model seems to have shown that this level of protection is probably not necessary, so if you don't need the thread safety then as of EJB 3.1, you can use a singleton session bean with bean-managed concurrency.
The thread safety restriction also gives some additional freedom to the EJB container for optimization. For example, if the EJB container knows that only one thread at a time can be using a stateless session bean, then it can manipulate the state of injected objects at method entry/exit so that those objects don't need use ThreadLocal (e.g., UserTransaction or SessionContext).

Related

Are ReaderInterceptor, WriterInterceptor thread safe?

I want to invoke stateless EJB from ReaderInterceptor, WriterInterceptor but I'm not sure is this interceptors can I inject EJB or I need every time lookup EJB?
Specification jax-rs 2.0 say nothing about creating instance for each request. So, it's not thread safe
§6.4 of the JAX-RS 2.0 specification states:
... a single instance of each filter or entity interceptor is instantiated for each JAX-RS application. ...
Therefore your interceptor is by definition a singleton. However, the injection point for your EJB will consist of a proxy that takes care of providing access to an unused instance of the stateless EJB each time it is invoked. It may find it in a pool of pre-created instances or it may just create and initialise a new one.
Additionally, §4.10.13 "Non-reentrant Instances" of the EJB 3.2 specification states that:
The container must ensure that only one thread can be executing a stateless or stateful session bean instance at any time. Therefore, stateful and stateless session beans do not have to be coded as reentrant. ...
In summary, just inject your EJB. The container will look after thread safety issues on your behalf.

thread in a webapplication (servlet, Spring , hibernate)

I understood the basic concept of Thread in standalone application. But, got confused in below areas.
1). In Java webapplication (servlet and Spring based)?
I hope, each request is handled by a different thread. Is this correct? Is there any other definition available?
2). what is a thread in Hibernate with Spring MVC?
Session factory is thread safe.. where as session object is not. What is mean by thread here?
Please help me to understand this.
1) The application server has a thread pool, when a request comes in it gets assigned a thread from the pool.The same thread calls the dispatcher servlet, which calls a controller, which calls a service, etc., and finally creates an HttpResponse and sends it to the client.
2) A usual pattern with Hibernate (if you're not using Seam conversations) is session-per-request:
2.4.2. Session-per-request pattern
This is the most common transaction pattern. The term request here
relates to the concept of a system that reacts to a series of requests
from a client/user. Web applications are a prime example of this type
of system, though certainly not the only one. At the beginning of
handling such a request, the application opens a Hibernate Session,
starts a transaction, performs all data related work, ends the
transaction and closes the Session. The crux of the pattern is the
one-to-one relationship between the transaction and the Session.
The transaction is stored by Spring in a threadlocal variable. So the thread has a Hibernate session (which is confined to that thread), and it is associated with a transaction (or a stack of transactions, since they can be nested).

EJB Service Locator with caching

I am using a Service Locator implementation which caches the result of javax.naming.Context#lookup call, and maps it to the requested EJB interface, so all subsequent requests (for the same EJB) after the first one, return the cached instance.
My concerns are:
Since the same instance is used, there is no utilization of the
server EJB pool which would serve multiple simultaneous requests
with multiple EJBs (unless the underlying server logic somehow makes
use of the EJB pooling)
Stateless and stateful EJBs are thread safe, but since, again,
only one instance per EJB class is used, and EJB has EntityManager
injected via #PersistenceContext, I assume that means that multiple
threads could be using the same EntityManager instance (not just the
persistence context), which definitely is not thread-safe
Do you think that it's best not to use caching in the Service Locator, or that my concerns are unjustified regarding EJB behavior?
What you get from the lookup operation (through the JNDI service) is an object called Stub and him is not fixed with any special EJB instance.
Once cached, every time you invoke an EJB service the stub is able to select a different EJB instance from the pool (this apply to stateless); even in a cluster environment, the stub object is able to select an EJB instance from different servers.
Therefore, caching the stub object should not be a problem.
Notice that I'm talking about stateless, I think that caching doesn't make sense to statefull session bean.
The EJB lookup is a time-consuming operation, so caching improves the client performance.
About your comment:
If you were using EntityManager inside a component that is used by multiple concurrent threads like a Servlet, yes, you will have to care about concurrency, but the EJB's Tread Model imply that will not be several thread using the same EntityManager instance at the same time, so the fact that EM is not thread safe doesn't matter.
What concerns me still is the fact that different EJBs are using the
same injected (via #PersistenceContext) EntityManager instance
I think that for simple sceneries the best way to think about it, if as describe here:
The most common pattern in a multi-user client/server application is
entitymanager-per-request. In this model, a request from the client is
send to the server (where the JPA persistence layer runs), a new
EntityManager is opened, and all database operations are executed in
this unit of work. Once the work has been completed (and the response
for the client has been prepared), the persistence context is flushed
and closed, as well as the entity manager object.
This will be more difficult to check ;)

EJB and Synchronization

Are Session Beans (stateless session beans, stateful session beans) Synchronized?
Only one thread at a time will be accessing your beans. It is up to the application server to manage this. So you should not be using synchronized from within your beans. This is why a non-threadsafe like EntityManager can be an instance value and not have synchronization issues.
Stateless beans:
Every thread/request will get different instance of EJB from pool. SLB should not hold any user session data, any state. The same code may be executed in parallel. One instance is accessed by one thread at a time.
Statefull beans are synchronized for user session. Every user will get own session scoped instance. Second thread/request will wait until the first thread finishes. Statefull EJB can hold user specific data. One user cannot execute same code in parallel. Different users may execute same code in parallel.
If accessing a resource that does not allow parallel access use Singleton EJB. As name implies there is only one instance. By default EJB Singleton can be accessed only by one thread (Container Managed Concurrency and #Lock(WRITE)).
Stateless/Stateful session beans are thread safe. Because each request will get a dedicated instance of the bean and so it doesn't need to be synchronized.
Singleton session beans are shared and needs to be synchronized either by the container (Container Managed Concurrency - CMC) or by the user (Bean Managed Concurrency - BMC).
Very True thing about EJB beans is that once you have created EJB 3.0 beans then the methods of the EJB is by default Synchronized.
e.g.
#Statelss
Class EJBclass {
void someMethod(){
}
}
now if you will make this someMethod Synchronize it will show Error like it is can not be Synchronize at this level as it is synchronized.
EJB 3.0 Beans are smart and performance is good.
Enterprise java beans are not synchronized . As session beans are maintained by ejb container so you have to implement synchronization logic in application level.

Why pool Stateless session beans?

Stateless beans in Java do not keep their state between two calls from the client. So in a nutshell we might consider them as objects with business methods. Each method takes parameters and return results. When the method is invoked some local variables are being created in execution stack. When the method returns the locals are removed from the stack and if some temporary objects were allocated they are garbage collected anyway.
From my perspective that doesn’t differ from calling method of the same single instance by separate threads. So why cannot a container use one instance of a bean instead of pooling a number of them?
Pooling does several things.
One, by having one bean per instance, you're guaranteed to be threads safe (Servlets, for example, are not thread safe).
Two, you reduce any potential startup time that a bean might have. While Session Beans are "stateless", they only need to be stateless with regards to the client. For example, in EJB, you can inject several server resources in to a Session Bean. That state is private to the bean, but there's no reason you can't keep it from invocation to invocation. So, by pooling beans you reduce these lookups to only happening when the bean is created.
Three, you can use bean pool as a means to throttle traffic. If you only have 10 Beans in a pool, you're only going to get at most 10 requests working simultaneously, the rest will be queued up.
Pooling enhances performance.
A single instance handling all requests/threads would lead to a lot of contention and blocking.
Since you don't know which instance will be used (and several threads could use a single instance concurrently), the beans must be threadsafe.
The container can manage pool size based on actual activity.
The transactionality of the Java EE model uses the thread context to manage the transaction lifecycle.
This simplification exists so that it is not necessary to implement any specific interface to interact with the UserTransaction object directly; when the transaction is retrieved from the InitialContext (or injected into the session bean) it is bound to a thread-local variable for reuse (for example if a method in your stateless session bean calls another stateless session bean that also uses an injected transaction.)
Life cycle of the Statelesss session beans are Doesnot exist, Passive and MethodReady(Passive or Inactive) state.To optimize on perormance, instead of traversing the bean all through from create to method ready state, container manages the bean between active and passive states through the container callbacks - ejbActivate() and ejbPassivate() there by managing the bean pool.
sreenut
Methods by nature ARE THREAD SAFE (including static). Why? Simple, because every variable inside the method is created in the stack memory, i.e. every variable used inside the method is created per call (it's not shared). However, parameters aren't part of the stack.
However, a method is unsafe if it uses an unsafe variable:
a) calling a static field or variable. However, it happens in every single case.
b) calling a resource that it's shared. Such as the EntityManager.
c) passing a parameter that is not safe.

Categories

Resources