4.2. Stateful Session Bean

As a stateful component, stateful session beans require a different implementation from the container. First, because they maintain state, that state is associated exclusively with one client, so there is only one instance per client. Second, because they maintain state and are tied to one client, the container must prevent any concurrent modification to that state. Third, because they maintain state, that state has to participate in replication for a clustered environment. Finally, if the instance is not accessed in a period of time, and the bean is not canceled, the state may be passivated to disk. All these factors play a role in the throughput that can be achieved when using stateful session beans. It's important to choose the right state management solution for your application. Stateful session beans can be useful, especially where the number of concurrent users is not too large- i.e. into millions.
To help with understanding the difference that a stateless vs. stateful approach can have, consider a real-life situation where a stateless approach was the imposed standard. In this situation there was an entire set of services in the application that looked-up data for users for use in maintenance tasks, or placing orders, etc. In almost all cases, these “look-ups” would return more data than the user could effectively deal with, and there was logic in the client to page through the list. As it paged through the list, if it needed to get more data than was on the client at that time, it called the server again. When it did this it actually passed a row number to the server to say, starting at this row number, return back the next set of rows. This made the queries very complex, as the queries themselves had to scroll through the data and return the correct set. Of course the user could page down through, but also back up again, and this process was repeated many times in certain cases. So, the design was stateless, but the load it actually exacted on the database was extraordinarily high, and the response time of the services themselves suffered. Users complained of poor response times as well. To solve this issue the services were made stateful (with one instance per client), the paging logic was removed from the queries themselves, and scrolled through the data in memory as the client paged through the rows. All queries were limited to a maximum number of rows, because returning more than that meant that the search criteria for the look-up should be expanded to narrow down the result set to make it usable for the end user anyway. The results of the change to a stateful approach were a significant decrease in database load and an improvement in response times. This is a good example of how stateful session beans can be used, and used effectively.

4.2.1. Stateful Configuration

There are two aspects of stateful session beans to be considered: the underlying cache that supports the life-cycle of the bean and replication of the bean's state.
In the same file that configures HTTP session replication is the configuration for stateful session bean replication. The configuration file is jboss-cache-manager.sar, in the directory JBOSS_EAP_DIST/jboss-as/server/PROFILE/deploy/cluster/jboss-cache-manager.sar/META-INF. Note that the default, standard and minimal configurations do not have the clustering configuration, nor the clustering code deployed. In this file is an entry called sfsb-cache, as seen below:
<!-- Standard cache used for EJB3 SFSB caching -->
<entry><key>sfsb-cache</key>
<value>
   <bean name="StandardSFSBCacheConfig" class="org.jboss.cache.config.Configuration">
<!--  No transaction manager lookup -->
<!-- Name of cluster. Needs to be the same for all members -->
<property name="clusterName">${jboss.partition.name:DefaultPartition}-SFSBCache</property>
<!-- Use a UDP (multicast) based stack. Need JGroups flow control (FC)
   because we are using asynchronous replication. -->
<property name="multiplexerStack">${jboss.default.jgroups.stack:udp}</property>
<property name="fetchInMemoryState">true</property>
<property name="nodeLockingScheme">PESSIMISTIC</property>
<property name="isolationLevel">REPEATABLE_READ</property>
The two most important configuration parameters are the node locking scheme and isolation level, which are analogous to databases. Pessimistic locking assumes that multiple clients should not own the lock on the data, in this case the data in the cache, at the same time. The isolation level is similar to the concept in database management systems. Since the container above this cache already prevents more than one client modifying the state of a bean, changing the node locking scheme provides no advantage.