Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why Stateless session beans?

I was reading about stateless session bean and couldn't understand it's use.

Excerpt from sun tutorial below

"..Because stateless session beans can support multiple clients, they can offer better scalability for applications that require large numbers of clients"

Where stateless session bean is being used? what kind of applications use it?

What mechanism has been being used before the advent of 'stateless session bean' to support multiple clients in the similar contexts?

Can anyone please provide some details?

thank you!

like image 803
Surez Avatar asked Apr 27 '11 20:04

Surez


3 Answers

To be honest, it is hard to find any reasonable use case for SLSBs. Since they don't hold any state (as the name imposes), they should be inherently thread-safe. Even though they are pooled by the container.

On the other hand it is tempting to use them as a safe temporary storage as they are guaranteed to be thread-safe (thanks to pooling), you don't need any synchronization or thread-safe collections. But consider the following pseude-code:

@Stateless
public class Slsb {
  private int counter;

  public void increment() {
    ++counter;
  }

  public int getCounter() {
    return counter;
  }
}

Client-side:

@Resource
private Slsb slsb;

public void clientMethod() {
  slsb.increment();
  slsb.increment();
  slsb.getCounter();  //???
}

This code (despite its vulgarity) is perfectly fine and it does not require AtomicInteger for instance.

What result do you expect? Actually, any non-negative value is possible... Any call to slsb might be served by different instance of Slsb and in the meantime your (previously used) instance might have been used to serve different clients. Conclusion: storing state in SLSB is wrong, but for some reason SLSBs are pooled to avoid threading issues when changing the state (?!?). Personally I much prefer singleton services (Spring-like) and I have never got the SLSB idea. And yes, I am aware of singleton EJBs in EJB 3.1.

like image 112
Tomasz Nurkiewicz Avatar answered Oct 10 '22 00:10

Tomasz Nurkiewicz


Having used EJB 3.0, in my opinion Stateless Session beans are there as to complete the Enterprise Bean landscape. They indeed are there to setup a Facade to the rest of your business logic. People often suggest SLSB's to be threadsafe, but this is misleading to say the least.

They are definitely not thread safe when their codepath includes calling non-threadsafe code (eg. a shared non threadsafe cache).The only guarantee that SLSLB give is that a single SLSB instance is used by at most one thread at the same time. This basically boils down to SLSB's having synchronized method access, and that there will be multiple instances to serve client calls. But having a SLSB method calling code from a shared non-thread safe class from these multiple instance could still wreak havoc and would render the SLSB in question non-threadsafe.

Since EE contexts (transactions , security resources etc) are bound to the thread already I see no need for SLSB over say Spring Singletons. They do complement Statefull Session beans in an EJB-only application.

In my opinion the route they choose with SLSB's and the new lock concurrency settings for EJB 3.1 is an attempt to dumb down the programmer and have the Mighty Container serve your needs. Do yourself a favor and go read Java Concurrency in Practice and start using singletons combined with stock java thread concurrency constructs. (synchronized, volatile, concurrent collections etc.)

like image 38
user698226 Avatar answered Oct 10 '22 00:10

user698226


In contrary to what most answers here let you believe, statelessness has nothing to do with threadsafety of the class itself. That's absolutely not the primary goal of @Stateless. The developer itself is still responsible for that the class representing a @Stateless EJB doesn't have any instance variables declared (i.e. no state). The container isn't responsible for that part. Basically, the developer must say "Hey container, here's a stateless business service class, I'll annotate it with @Stateless so that you can use it as a stateless EJB" and thus not the other way round or so.

If you want state, then use a @Stateful which will be newly recreated every time the client obtains it (so, if the client is e.g. a view scoped JSF managed bean, then the EJB will live as long as that bean, or if the client is e.g. a session scoped CDI managed bean, then the EJB will live as long as that bean, etc). Or, use a @Singleton which is basically application scoped and actually thread locked.

Statelessness and pooling has more to do with threadsafety of transactions. You probably already know that a single method call on a @Stateless counts by default as a single full transaction. However, that transaction in turn requires a thread lock on the specific EJB instance, because of all the sensitive pre- and post processing work. So the EJB could basically block all other clients wanting to call the same method until the transaction is committed. That is exactly why they are cloned and pooled on demand.

Do note that a @Singleton is not pooled and is by default actually thread locked. You should by now understand that a @Singleton is by default absolutely not faster than a @Stateless when (ab)used as a "stateless EJB". See also a.o. Java EE 7 tutorial "Managing concurrent access in a singleton session bean".

See also:

  • When is it necessary or convenient to use Spring or EJB3 or all of them together?
  • JSF request scoped bean keeps recreating new Stateful session beans on every request?
  • When using @EJB, does each managed bean get its own @EJB instance?
  • EJB @Asynchronous to retrieve real time inserted row in JSF seems to be thread locked
like image 27
BalusC Avatar answered Oct 10 '22 02:10

BalusC