Using EJB entity beans you can configure the bean so that when a thread has access to an EJB entity bean, no other threads can access the EJB bean. The container will block other threads until the thread with the lock is finished with the bean. Is there a "Spring way" to do this? Or do you have to just use the standard Java concurrency synchronization approaches to handle this?
If you're referring to pre-EJB3 entities, then this model is a bit broken, and probably not one you want to be following. Concurrent access to the same java object instance of a persistent entity should be avoided. Instead, each thread should obtain its own instance of the entity from the container.
The usual approach to controlling concurrent access to entities is to use transactions, and let the database take the strain. Spring+Hibernate/JPA is more than capable of this.
Related
I am really sorry to ask such a question, but I need a bit of your help.
As far I understand, if I use servlets all my business logic ( methods of which I call in controllers ) should be Thread-safe.
Does the same count for Spring? Do I need to make thread-safe methods in service layer when I use #Getmapping #PostMapping instead of using servlets directly?
I do appreciate your help a lot!
Thread safety is a different context . Singleton spring beans(default scope) has no relation with thread safety. Spring container only manages life-cycle of objects and guaranteed that only one object in spring container. So, if a Non thread safe object is injected then obviously it is not thread safe. To make it thread safe you have to handle it by coding.
If it is a web-application , Scope - request can achieve thread-safety as for each new request it creates a new object or Scope - prototype will do this.(for each invocation it creates new bean .)
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.
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.
In a traditional n tier web app with servlets for web layer and ejbs(2.0) for biz layer, what is the rationale behind making the servlet model multi threaded and the ejb model single threaded?
i.e there is only 1 servlet instance for all requests, but for ejbs, for each request, there is a new bean instance assigned from the bean pool.
There is indeed only one instance for a specific Servlet since they are supposed to be stateless. In practice this isn't always the case, but so be it.
There are however multiple instances of Stateless session beans (SLSB), and those are pooled.
By their very definition, stateless session beans are stateless, so on the surface this seems like a paradox. The things is that while stateless session beans are stateless with respect to individual calls being made to them, they in fact very often have state.
This state is in the form of references to other resources. The JPA entity manager, which is not thread-safe, is a prime example here. During a single call to a stateless session bean, the caller must have exclusive access to this resource. When the call returns, the next caller can have exclusive access, etc.
If a single instance was used, then either all callers would have to wait on each other (which is of course killing for performance), or they would have the access this single instance concurrently. In the latter case, the bean implementor has to do manual locking of the non thread-safe resources like the entity manager which is often brittle, error-prone and in the end still causes callers to wait on each other.
So, in order to improve performance and still have the safety guarantee, multiple instances are being used.
Those instances are then being pooled and re-used instead of created fresh for each request, because finding, initializing and injecting all required dependencies of the bean can potentially be time consuming.
All of this thus automatically also means that if you inject an entity manager or other non thread-safe resource into a Servlet (which is allowed), you may run into problems. This is a small loop-hole in the Java EE architecture, which is of course easily worked around by simply making use of stateless session beans.
I think that typically servlets present thin facade to the heavy logic implemented in EJBs. Servlets should be stateless and therefore there is no reason to create more than one instance of the same servlet.
If you are using stateless beans only I think that there is no reason to have more than one instance too. But statefull EJBs have state and therefore you need instance per simultaneous request.
I hope I did not say bullshit.
As per my understanding stateless session beans are used to code the business logic. They can not store data in their instance variables because their instance is shared by multiple requests. So they seem to be more like Singleton classes. However the difference is contain creates (or reuses from pool) the separate instance of stateless session beans for every request.
After googling I could find the reasoning that the Java EE specification says they are suppose to be single threaded. But I can't get the reason why the are specified to be SINGLE THREADED?
The SLSBs are single threaded because of the TX Context, Principal is associated with a bean instance when it is called. These beans are pooled and unless the max pool size is reached are processed in separate threads ( Vendor dependent).
If SLSBs were designed thread safe every call would have looked like a servlet doGet/Post with request info containing Tx Context , Security Context info and etc. So at least the code looks clean (developer dependent).
The primary reason stateless session beans are single threaded is to make them highly scalable for the container. The container can make a lot of simplifying assumptions about the runtime environment. A second reason is to make life easier for the developer because the developer doesn't have to worry about any synchronization or re-entrancy in his business logic because the bean will never be called in another thread context.
I remember the reasoning being discussed in the reviews of the original EJB 1.0 specification. I would look at the goals section of the specification. See http://java.sun.com/products/ejb/docs.html for the list of specifications.