This article is based on EJB3 in Action, Second Editionand the book will release on October 2011. It is being reproduced here by permission from Manning Publications. Manning publishes MEAP (Manning Early Access Program,) ebooks and pbooks. MEAPs are sold exclusively through Manning.com. All print book purchases include an ebook free of charge. When mobile formats become available all customers will be contacted and upgraded. Visit Manning.com for more information.
Stateless session beans are probably the most common bean type used in an application. A stateless session bean doesn’t maintain a conversational state. This means that session beans tasks must be completed in a single method call. This does not limit a stateless session bean to containing only one method. To the contrary, a stateless session beans usually contain at least several closely related business methods. Of the session bean types, stateless session beans have the best performance characteristics. To understand why, take a close look at figure 1 that shows a high-level schematic of how stateless session clients typically use beans.
Stateless session beans are pooled. This means that, for each managed bean, the container keeps a certain number of bean instances ready in a pool. For each client request, an instance from the pool is quickly assigned to service the request. When the client finishes, the instance is returned to the pool for later reuse. This setup using a pool means that a small number of bean instances can service a relatively large number of clients. Don’t forget that these one-shot methods come with a number of services provided by the container.
In this article, you’ll learn about developing stateless session beans. We’ll start off by first looking at when stateless session beans are appropriate.
When to use stateless session beans
Session beans should be used to encapsulate business logic when you need dependency injection, transaction management, concurrency, security, remoting, scheduling, and support for interceptors. You specifically use a stateless session bean when the business logic you are implementing requires these services and can be performed within a single method call and the response is tailored for the client. This is an atomic piece of work that maintains no state after the method completes. The client may maintain state but the stateless session bean does not. To expound upon these basic guidelines we need to look to the prototypical session bean and then step back and look at the bigger picture.
To understand when to use stateless session beans let’s consider the prototypical use case that best exemplifies a stateless session bean. A stateless session bean should be a class with several methods that perform related operations such as managing users, updating account information, or managing bids. The related operations are all one shot; the bean doesn’t maintain any state after the method invocation is completed from the perspective of the client. The methods consume services such as database connections and possibly require security to enforce access control. The business operations performed by the bean are not static. They aren’t serving up the same data regardless of the client.
Stateless session beans may use other stateless session beans. These stateless session beans may interact with other database tables, resources, and have additional security requirements. Beans may and often will, use other beans. Figure 1 shows a design with multiple stateless session beans interacting with each other. Each of these beans uses transactions and also has security authorization requirements. A failure in the SAP Integration Bean should result in a rollback in the transaction in the Inventory and Bid Manager Beans. In this example, stateless session beans are joining transactions started by the parent stateless session bean and this is possibly being propagated down several levels. Thus, when trying to decide whether to make an object a stateless session bean, we have to approach it from the perspective of the services the methods require and how they are consumed by their clients.
We’ve just identified when to use stateless session beans but consideration should also be given to when not to use them. If you aren’t using any container services, such as remoting, injection, database resources, and so on, making a class a stateless session bean isn’t beneficial and overall application performance can suffer. If functionality in question is simply saving form data to a database, a JSF backing bean with an injected persistence context is more appropriate. In other words, now that you are familiar with stateless session beans, don’t turn every non-JPA POJO into a stateless session bean.
Stateless session bean pooling
As we see in figure 2 session beans are pooled by the container.
Whenever a request arrives for a bean, the container allocates a bean. When the stateless session bean’s method returns, the bean is placed back into the pool. Thus a bean is either servicing a request or waiting for a request in the pool. The pool serves two important functions. First, it ensures that there are objects ready to service a request when one arrives. Second, the pool bounds the number of instances that can be created. By keeping instances around to service requests, we minimize the amount of time it takes to begin servicing a request. If, every time a request arrived at the server, an object had to be instantiated and database connections established, a significant amount of time would be wasted. It would be analogous to going to a restaurant and waiting for the restaurant to run out and hire another waiter. At the opposite end of the spectrum, too many requests could flood the server and overwhelm available resources. If the container created another stateless session bean each time one was needed, the application could eventually exhaust resources. There is a limit to the number of database connections that can be open as well as the number of clients that can be serviced concurrently. Create too many objects fast and then toss them away, garbage collection will kick in and slow the application. Hence, limiting the size of the pool is a necessity.
The benefits of pooling stateless session beans should be obvious. You want to minimize the number of objects created to keep garbage collection from impacting the application while at the same time keeping some instances around to service requests. The act of balancing these two comes down to performance tuning. Each application container does performance tuning a little bit differently. As you develop and test your application, the tuning of this pool will be necessary. For instance, consider some of the pool settings available in the Glassfish server:
- Initial and minimum pool size—The minimum number of beans to appear in the pool. The default is 0.
- Maximum pool size—The maximum number of beans that can be present in the pool. The default is 32.
- Pool resize quantity—The number of beans to be removed when the pool idle timeout expires. The default is 8.
- Pool idle timeout—The maximum number of seconds that a bean can reside in the pool without servicing a request before it is released for garbage collection.
These are only a couple of the pool settings—there are many more. The parameters available to tune a container are container specific. Thus, the containers compete on scalability and performance-tuning features. The important thing to remember is that, if you are not using stateless session beans and are implementing your homegrown solution, you want have to implement your own pooling solution and then optimize its performance. As you can see, a stateless session bean is providing a significant amount of functionality. Implementing and testing business functionality is one thing; building an efficient pooling system and testing the algorithms is a separate matter.
The specification for stateless session beans refers to the pool as the Method-Ready Pool. An object in the method ready pool may have instance variables storing data—there is nothing to prevent the bean from doing this. However, given that there are numerous instances and that each method invocation is potentially and randomly a different client, member variables aren’t too useful unless they are used for internal purposes. For example, a method may load a complex object into memory and then store it in a member variable. The member variable can then be accessed from utility methods that are part of a call; you invoke method A, method A then invokes protected method B, and so on. This can be very dangerous because data could leak between method calls on a stateless session bean if precautions are not taken. Pooling stateless session beans is one of their key features.
We discussed the mechanics of stateless session beans—how to define them and how to pool them. We’ve explained when to use a stateless session bean.