I have been studying ejb recently and I am also reading about the timer service as well, but even though I have read about Stateless, Stateful and Singleton types of Session Beans, I still have some trouble to figure out what makes the Timer Service have a multiple instance attribute.
I have seen some examples around, and even the simplest ones use the Singleton Session Bean, so, If I were to write a simple program to test it, would it be ok to use a Stateless Bean or is it recommended to use a Singleton anyway? Also, if possible, can I have a case where a Stateless would not be optimal?
Use a singleton if you want to ensure that all timeout callbacks are invoked on the same underlying bean instance. This is important if you want to maintain state in the bean instance itself, and you want to ensure that only one timeout callback can be invoked at a time (by default, the timeout callback will use the singleton's concurrency management settings, which by default is container-managed with a write lock, so only one method on the singleton can be invoked at a time).
Use a stateless if you want to allow multiple timeout callbacks to be invoked at once. The EJB container will create new bean instances if there are multiple timeout callbacks happening concurrently.
If you want to configure a non-persistent timer to begin running when the application begins running, then you can either use the #Schedule annotation on either a stateless or singleton bean, or you can use an #Singleton #Startup bean with an #PostConstruct (and if you want the stateless behavior, you can inject the stateless bean into the stateless bean and invoke a createTimer on the stateless session bean during startup).
The reasons it uses singletons are at least 2 fold:
1.
only singletons have the capabilities of start up initialization. That means, you are able to register your timer services when your application starts.
2.
if it were to use stateless beans, then a new timer service will be registered with every stateless bean setup to serve a request. A singleton guarantees that only one of a kind of your timer is registered. Imagine a contention or integrity issues, or money losses, were you to inadvertently use a timer in a stateless bean and then more than 1 is created at more or less the same time to serve requests.
Related
I know that:
For stateless session beans the server can maintain a variable amount
of instances in a pool.
Each time a client requests such a stateless bean (e.g. through a
method) a random instance is chosen to serve that request.
My question is: Why a pool is needed?
Shouldn't one instance of a EJB stateless bean be enough to serve all requests ?
Also if the server for a given stateless bean is using a pool of 10 instances,
is 10 the maximum number of requests it can handle on such a bean ?
Can you help me clear my doubt?
EDIT:
section 4.3.14 of the ejb 3.1 spec gives the answer.
4.3.14 Serializing Session Bean Methods The following requirements apply to Stateless and Stateful session beans. See Section 4.8.5 for
Singleton session bean concurrency requirements.
The container serializes calls to each stateful and stateless session
bean instance. Most 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.
The container must serialize all the container-invoked callbacks (that
is, the business method interceptor methods, lifecycle callback
interceptor methods, timeout callback methods, beforeCompletion, and
so on), and it must serialize these callbacks with the client-invoked
business method calls.
Searching a bit online, my quess is that a thread pool is necessary
to the specification that imposes that EJB stateless methods
are thread safe.
So if we have,say 10 beans in the pool, only 10 requests can be served simultaneously, the other will be queued and assigned to the first free bean.
Please correct me if I'm wrong.
If you create a stateless session bean, It does not care about which client is calling, It allow you reuse the instances across multiple clients, with this you are going to have a better performance in your application, It is one of the principal differences between a stateless session bean and a stateful session bean.
A stateful session bean is going to create one instance per client and it is going to reduce the performance of the application because you are going to have many instances at the same time.
To have a pool allow you to increase the number of stateless ejb instancess depending of the load of your application :)
Edit
If you want only one instance to all the request and it is all that you need you can use a singleton session bean instead of a stateless session bean the stateless session bean was made for this operations that does not require of a state and this operation are going to help you to increase the performance.
If you have a pool with 10 instances you can receive any number of requests but only 10 instances are going to attend them .
Single stateless EJB instance can handle all requests theoretically but too slow.
Performance is main achievement in maintaining stateless EJB pool. Pool saves time in creating the EJBs and acquiring any predefined resources to process the incoming requests. Container guarantees the thread safe behavior so performance is really boosted with multiple ready instances in pool.
Also if the server for a ginen stateless bean is using a pool of 10 instances, is 10 the maximum number of requests it can handle on such a bean ?
With Pool of 10 instances can handle 10 simultaneous requests same time.
Stateless EJB are not state-less. (duh?)
I explain. A stateless EJB has some states, such as a flag for know if the EJB is running/sleeping or if the EJB is loaded and so on. I.e., a stateless EJB has hidden fields.
I am learning about EJB's, so far I have read that multi-threading is not allowed in EJB'S, because it is the container who should care about thread-safety and let the developer only focus in the business logic, so basically that means that EJB ensures that only one thread has access at the same time to a method in a Session bean.
What happens then when we have many users accessing to the same method in a EJB?
Is the container serializing the acceses, or is creating different instances of the bean, one per thread?
Could someone explain me what is the policy about that? Also I am a bit confused, why if multithreading is not allowed, so we cannot create our own threads, why we have this #Asynchronous annotation?
Yes, it creates several instances, and pools them. See the official Oracle documentation:
Because a stateless session bean is never passivated, its lifecycle has only two stages: nonexistent and ready for the invocation of business methods. Figure 22-4 illustrates the stages of a stateless session bean.
The EJB container typically creates and maintains a pool of stateless session beans, beginning the stateless session bean’s lifecycle. The container performs any dependency injection and then invokes the method annotated #PostConstruct, if it exists. The bean is now ready to have its business methods invoked by a client.
At the end of the lifecycle, the EJB container calls the method annotated #PreDestroy, if it exists. The bean’s instance is then ready for garbage collection.
I have this new mvc project where all beans are default scoped(no prototype or session).
with single application context.
i want to know
by making all beans to be default scoped are we trying to achieve the whole application to be run in single thread?
if so will that make each httprequest(from multiple or same sessions) to be queued until the previous one completes?How to avoid such scenario any advice or link would be helpful.
I am relatively new to spring and java development.
Because Spring beans are typically stateless, you can safely call them from multiple threads. That's how your application works: there is only one instance of every controller, service, DAO, etc. But your servlet container (through Spring) calls these beans from multiple threads - and it's completely thread safe.
In fact in plain servlets the situation is the same - there is only instance of each servlet and it can be accessed by infinite number of threads. As long as this servlet is stateless or properly synchronized.
Do not confuse Spring with stateless session beans in ejb that are pooled and each client gets its own instance from the pool.1
1 - In fact that's a bit dumb - since the beans are stateless by the definition, there is no point in pooling them and preventing concurrent access...
Singleton means that the there will be only one instance of each bean. Generally, such beans are processing elements that carry no state. The methods called on them are passed the context which contains the inputs to work on. Hence the method calls on such singleton beans are inherently thread-safe.
In a code base that I've inherited, there's an MDB which is calling SingletonBeanFactoryLocator().getIntance().useBean() to get a factory reference in its ejbCreate(), and then getting a specific bean from this factory and storing it as an MDB instance variable. (The factory is of type 'ClassPathXmlApplicationContext').
The confusing part is: after that bean is obtained, it's calling 'release()' on this factory reference in that same ejbCreate().
Now, this MDB is pooled with poolsize 'x' and what I've observed is, beans defined in the context xml are getting created 'x' number of times. So my guess is, every time the 'ejbCreate()' executes, it's creating a context and its beans afresh.
I checked Spring doc for 'release() above which says:
In an EJB usage scenario this would normally be called from `ejbRemove()` and `ejbPassivate()`.
So here're my questions:
1) is it really creating a new context and new beans everytime ejbCreate() is called?
2) if yes, what happens to the context/beans created in the previous call (e.g. if the beans are singleton themselves, will they be destroyed)?
3) is this the right way to use SingletonBeanFactoryLocator (possibly for thread safety issues) in the context above?
4) if not, what is the right way to use it?
EDIT: one possibility I can think of is to make the concerned beans prototype to make each MDB instance thread-safe, so there's no need to release and recreate the context. Awaiting other comments/suggestions.
Yes
Nothing happens. The same objects will still be in the same MDBs. The MDB doesn't care and Spring is out of the picture at this point.
That really depends on the use circumstances. If you just use Spring to assemble objects and every MDBs should have it's own instances then the answer is yes.
Depending on the use case SpringBeanAutowiringInterceptor may or may not be a better alternative.
Prototype can be tricky. You have to understand your beans and the consequences well to make it do what you expect. That's why it's generally best to make spring beans stateless.
Update:
There is actually a race condition. If the container decides to run the ejbCreate() of two MDBs in parallel then they both will end up sharing the same application context.
Update 2:
I could not find a section that explicitly allows EJB creating through parallel threads but I could also not find a section that explicitly forbids it.
Given the following sections from the spec I assume it would be in the spirit of the spec to do it.
2.4.2 Message-Driven Objects
A typical EJB container provides a scalable runtime environment to execute a large number of mes- sage-driven objects concurrently.
5.2 Goals
A further goal of the message-driven bean model is to allow for the concurrent processing of a stream of messages by means of container-provided pooling of message-driven bean instances.
5.4 Protocol Between a Message-Driven Bean Instance and its Container
It is the container’s responsibility to ensure that the message-driven bean comes into existence when the container is started up and that instances of the bean are ready to receive an asynchronous message delivery before the delivery of messages is started.
5.4.11 Concurrency of Message Processing
A container allows many instances of a message-driven bean class to be executing concurrently, thus allowing for the concurrent processing of a stream of messages. No guarantees are made as to the exact order in which messages are delivered to the instances of the message-driven bean class, although the container should attempt to deliver messages in order when it does not impair the concurrency of mes- sage processing.
I am working on an EJB3 application with mainly stateless session beans (SLSB). They use container managed transactions (CMT).
I want the beans to be aware of the transactions (for logging, etc). I can implement the javax.ejb.SessionSynchronization to do this. I find that I can register a javax.transaction.Synchronization in a default interceptor also to get similar callbacks.
Are there any dis/advantages to using one over the other?
Multiple SLSB of the same type can be involved in the same transaction. As soon as a method exits, the SLSB is returned to a pool for use by the next invocation, so it is not safe for an SLSB instance to be "aware" of a transaction: by the time it is notified, the bean might be in use in another transaction.
As for SFSB, I would say there is no advantage between the two approaches in theory. However, the EJB container might be using Synchronization for various internal tasks, so using SessionSynchronization would allow the EJB container to have more control over the timing of the callbacks with respect to its own operations.
I just tried to use the javax.ejb.SessionSynchronization interface with a stateless session bean and was confused not to get any calls of the three implemented methods. Then I saw this comment in the javax.ejb.SessionSynchronization JavaDoc:
Only a stateful session bean with container-managed transaction demarcation can receive session synchronization notifications. Other bean types must not implement the SessionSynchronization interface or use the session synchronization annotations.
See also this thread for some more background. So my conclusion is that making stateless session beans transaction-aware using CMT can NOT be achieved with javax.ejb.SessionSynchronization.