Stateful Session EJBs: Beasts of Burden
10/02/2001That's right. You heard it here first. I'm calling Stateful Session EJBs (SFSBs) the J2EE beasts of burden. I don't care for them. I despise them. I really hate them.
I don't dislike what they offer to developers. Rather, I dislike their conniving, misleading, and subtle nature that permits developers to make some of the worst architecture decisions I've seen. SFSBs have a very limited use in development and should rarely be seen. But somehow, these infiltrating creatures have wormed their way into designs where they do not belong. This article discusses the true purpose of SFSBs, where they belong in a J2EE design, and the situations where they should not be used. Heed this advice and perhaps we can harness the beast to create more robust architectures instead of creating more burdens by using SFSBs incorrectly.
The intent of Stateful Session EJBs
An Stateful Session EJB is a server-side object designed to hold data on behalf of a particular client. SFSBs should be used to store session-oriented data. Session-oriented data is used to track a multi-request sequence, ordering, or any associated data that is part of a sequence. SFSBs, however, have a limited lifespan and are not intended to survive server crashes. SFSBs are the only type of EJB that can receive callback notifications about the lifecycle of transactions that the bean participates in.
When SFSBs should not be used
SFSBs are not server-side data caches. Yes, they do hold data in the server on behalf of the client, but that does not make them an in-memory, persistent store data cache. Yes, SFSBs are allowed to access a database and load data into memory, but the act of cacheing persistent data lies within the responsibilities of entity beans. A primary requirement for a data cache is that multiple clients should be able to access the same data concurrently based upon locking rules dictated by the developer. SFSBs are not designed to be shared resources to intuitively allow for this type of concurrent access. In the EJB 1.1 specification, concurrent client access of SFSBs was strictly prohibited. In EJB 2.0, a container vendor's implementation may permit concurrent client access of a single SFSB. Despite this new capability in EJB 2.0, SFSBs should not be used in a design that calls for multiple client concurrent access because they make it easy for a developer to code a deadlock.
The only data that should be cached within an SFSB is data pertaining to tracking the sequence that the SFSB is managing. I've seen too many clients take 30 minutes to build an SFSB with persistent data and then spend 30 days trying to architect a solution that converts the bean into a transaction-aware data cache. Just don't do it -- you are setting yourself up for guaranteed failure.
Related Reading
Enterprise JavaBeans, 3rd Edition
By Richard Monson-Haefel
Table of Contents
Index
Sample Chapter
Full Description
Read Online -- SafariPart of this misperception about SFSBs comes from the wording within the EJB specification itself! The EJB specification suggests that a shopping cart for an e-commerce system could be implemented with SFSBs. This is perfectly acceptable if that shopping cart is only intended to be an in-memory implementation that does not need to survive a server crash. In reality, however, most implementations of shopping carts are required to survive server crashes; the data contained within the shopping cart needs to be persistent and transactional -- with an in-memory data cache.
Developers may be confused because if you read the EJB specification incorrectly it could be interpreted as saying all shopping cart implementations can be implemented with SFSBs. That simply isn't true. All in-memory shopping cart implementations can be implemented with SFSBs, but if you need to implement a persistent, crash-friendly shopping cart, you need to use entity EJBs.
SFSBs are not distributed data stores. Yes, many application servers provide SFSB replication of state to allow for failover of requests to provide a higher level of availability. SFSB replication is just that: a replication mechanism to resist failures of instances on a single machine. SFSB replication is not designed to resist cluster-wide failures nor is it designed to cache data across an entire cluster. If a cluster has SFSB replication and all of the servers hosting a particular SFSB crash, that SFSB is permanently lost. This will happen, even if there are other servers that are still active. This is perfectly acceptable and should be accounted for when using SFSBs. If an SFSB is only used as a session-oriented component, the worst-case scenario that occurs is that the sequence is restarted from scratch when all copies of a particular SFSB are destroyed.
When SFSBs should be used in non-web systems
For systems that do not have a servlet/JSP front-end, SFSBs should be used to track session-oriented state similar to the way a web-based system would use an HttpSession object. This was the primary intent of SFSBs when they were created.
When SFSBs should be used in web systems
Systems that have JSP/servlet front-ends should use HttpSession objects to store session-oriented state on behalf of a client. Applications that manage an HttpSession object and an SFSB for a single client wind up duplicating effort that does not need to be duplicated. There are two reasons to use an SFSB in conjunction with an HttpSession object:
Your application server does not provide cache management of
HttpSessioninstances and your system is expected to have a large number of concurrent clients. Containers for SFSBs can activate and "passivate" the state of instances to and from a secondary store. This allows a container to create an upper limit to the number of instances that will exist in memory at any given point in time. The number of concurrent clients can exceed the limit of SFSB instances in memory because the container can swap idle instances to and from the secondary store. The container will never allow more than the limit of SFSB instances to exist in memory, subsequently placing all additional instances into the secondary store. This provides a greater level of scalability to the system through effective memory management.Many application servers provide similar cache management of
HttpSessionobjects. BecauseHttpSessionobjects are similar to SFSBs, they can also be made passive and active. Cache management behavior ofHttpSessionobjects is not required as part of J2EE and is considered a vendor value-add. If your application server does not supportHttpSessioncache management -- and you need to control the total number of session-oriented instances in memory at any given time -- you should place the bulk of your session-oriented data in an SFSB instead of anHttpSessionobject. You will still need to maintain anHttpSessionfor each client, but the only item in theHttpSessionshould be a reference to the SFSB for that client. If the only item in theHttpSessionobject is a reference to the SFSB, the amount of memory consumed by eachHttpSessionobject is minimal and cache management of these instances is not needed. The bulk of memory consumption will occur within the SFSBs, which have a standardized strategy for allowing a container to perform cache management.Your session-oriented objects need to receive notifications on the lifecycle of the transactions they participate in. SFSBs can implement the
SessionSynchronizationinterface. TheSessionSynchronizationinterface contains three methods that a container invokes as a transaction migrates through the lifecycle the SFSB is participating in. An SFSB might implement theSessionSynchronizationinterface as a way to return the data of the SFSB to its original state whenever there is a transaction rollback.HttpSessioninstances do not have a mechanism that allows them to receive transaction notifications. This means that any data that is modified in anHttpSessionduring a transaction will not be reverted if the current transaction is rolled back. All changes to data in anHttpSessionobject are always durable despite the outcome of any executing transactions. If this behavior is not appropriate for your system, placing all data into an SFSB instance that implementsSessionSynchronizationwill give you the appropriate behavior.
Conclusion
SFSBs have their place in J2EE systems; it's just very small. If your designs use SFSBs for session-oriented data and avoid using SFSBs as distributed data caches, your systems will be more reliable. If you have a requirement you think SFSBs can satisfy and that requirement is not listed in this article, you should give some hard thought to another solution.
Tyler Jewell , Director, Technical Evangelism, BEA Systems Tyler oversees BEA's technology evangelism efforts that are focused on driving early adoption of strategic BEA technologies into the ISV and developer community.
Read more EJB 2 columns.
Return to ONJava.com.
You must be logged in to the O'Reilly Network to post a talkback.
Showing messages 1 through 9 of 9.
-
why Deadlock?
2007-01-30 23:04:26 AnupamaD [Reply | View]
why we are doubting about the deadlock situation? the name itself suggests that it is a session bean..my understanding one session will hold one bean at a time for a client. so there is no concurrency problem...as every client will hold his reference to make calls to...
-
more reasons to use SFSB ...
2005-03-10 03:41:25 bravegag [Reply | View]
Hi,
There are couple more reasons I can think of for using SFSB even on top of a J2EE Web Application:
1-. Better distribution of responsibility i.e. encapsulation: In order to avoid state on SFSBs at all costs the Web Tier IMHO should never implement "Business Logic" inherent to the "Application Tier" just because this "Business Logic" has to keep short-lived conversational state with remote clients. Moving business logic away from SFSB to the Web tier breaks encapsulation and distribution of resposibility in the application implying **real evil** consequences i.e. a system much harder to maintain and extend.
2-. Poor reusability and integration: Again, avoiding the supposedly "evil" SFSB at all costs will consequence lower reusability as the moved functionality will not be able to be reused directly from non-Web Application clients e.g. exposing the SFSBs as Stateful Web Services for B2B integration.
I think that any technology can be easily misused, SFSB is not the exception, all have their place. I think also that moving conversational state inherent to the J2EE application "Business Logic" anywhere else out of the SFSBs is a HACK and will consequence that the application will not migrate well to evolving specifications and improved implementations of J2EE Servers. After all, Application Server Providers expect to find Your "Business Logic" state in the SFSBs.
Best Regards,
Giovanni
-
reentrant Stateful Session Beans
2004-05-20 07:56:47 dirkhogan [Reply | View]
I was suprised by the following sentence:
"In EJB 2.0, a container vendor's implementation may permit concurrent client access of a single SFSB."
That is not my understanding. From the ejb 2.1 spec:
"Clients are not allowed to make concurrent calls to a stateful session object."
The spec goes on to say that a given vendor container implementation "may instead queue or serialize such concurrent requests"(from a footnote). I suppose this is what the author is referring to, yet technically this access is not concurrent - a given vendor implementation may choose to serialize concurrent access attempts. This does not make access to a stateless session bean concurrent.
-
Multi Tier?
2003-03-06 07:00:17 anonymous2 [Reply | View]
I've got the feeling the author is neglecting a multi-tier environment. Because in a multi-tier environment I want my ssejb to act as a Session instance, but on the data-tier.
-
O'really good one
2002-01-03 22:42:19 ajayjindal [Reply | View]
Hi !
this article is very good for those who are always getting confused why not SFSB in place of entity beans and if not why they are there.Explains all the stuff needed to understand.
Wishing all a very very happy new year 2002!
bye,
Ajay Jindal
-
What about nearly static data?
2001-12-21 04:45:29 jonathan.oconnor [Reply | View]
I have a table containing information about the world's currencies (name, ISO code, decimal places, etc...) This information changes maybe once or twice a year. Most of my business logic needs to access this data often, so naturally I want to cache it. The $64 question is, how?
My natuarl inclination is to create a singleton class (probably static methods) which reads teh DB table at initialization or first use.
Then I just use this anywhere I need it. But what happens if I want to refresh the data? Can I use EJBs for a better solution? It should give fast access to the data.
From reading your article, it seems that I shouldn't use a SFSB to do this.
Very interested to hear your advice,
Jonathan O'Connor -
What about nearly static data?
2005-08-10 11:44:25 palaniappan.rajaram [Reply | View]
Hello Jonathan,
Three and half years later I'm faced with the same design issue. I too have some static data which change once in a few days, in the middle of the regular hours of operation. Obviously, restarting when many users are logged in, is not an option.
Have you found a better solution than a singleton? That was my original approach but refresh became a hassle. Now, I'm debating if I should use a "stateless" session bean (just one instance of it) which should have the following:
- hashtable for the objects from the database
- public getter method to retrieve an object
- refresh method which when called should block access to the getter method until refresh is completed
I would appreciate any feedback that you can provide.
Thanks
Raj
prajaran@mindspring.com
-
What about clustering
2001-10-04 00:14:25 ampieb [Reply | View]
In a database based web clustering architecture, like WebSphere's, one would store session info in a central session bean rather than in an HttpSession. The web clustering would then require much less database overheads, since only the handle to the session bean needs to be stored centrally, not the entire session bean. It really depends on what you want from your architecture, and where you want the bottlenecks to be. As with any technology, you just have to know where to use it. Technology is not conniving and misleading, developers make stupid decisions. -
What about clustering
2001-10-08 06:01:10 kestrel [Reply | View]
> Technology is not conniving and misleading,
> developers make stupid decisions.
I agree with you on both points: technology is not misleading, and in my experience as a middleware developer I have made many stupid decisions. However, I think Tyler's point about the EJB Specification being misleading with respect to the applicability of Stateful Session Beans is a valid one.
There is no reference implementation of the EJB specification; if a developer wants to explore a particular issue, he has two options:
- Try it out on whatever app server is available. There are, of course, few guarantees that the functionality of a particular app server will be duplicated on any other J2EE-compliant server.
- Read the EJB Specification to determine the minimum guarantees made to developers for that particular aspect.
The authors of the EJB 1.1 and 2.0 specifications have made an exceptional effort in making the material accessible to all developers, partially through the use of examples such as the "Shopping Cart" example in question. This particular example, however, can be misleading if your concept of the functionality of a shopping cart includes persistent failover. - Try it out on whatever app server is available. There are, of course, few guarantees that the functionality of a particular app server will be duplicated on any other J2EE-compliant server.




