• 沒有找到結果。

Entity Bean Transaction Model

在文檔中 WILEY advantage (頁 63-67)

First, take a look at the model used by Entity Beans. Bean developers can either man-age the transaction demarcation themselves using bean-manman-aged transactions, or they can use the container’s transaction management service. This second option, called container-managed transactions, relies on the transactional nature of Entity Bean meth-ods to be declared in the deployment process. There are a couple different transaction settings for a method,REQUIRES,REQUIRES_NEW, andSUPPORTSbeing the pri-mary ones. If a method is declared to require a transaction, the container automatically

N OT E

starts one if the method call is not already part of an overall transaction. Any container-managed operations or Bean-Managed Persistence code sharing the same JDBC data source can participate in the database transaction. The transaction is committed after the highest level method that started the transaction completes, unless any one of the components participating in the transaction invokes the EJBContext.

setRollbackOnly()method.

Once in a transaction, a client usually makes a request to obtain a particular instance of an object. An Entity Bean client uses a finder method to locate an instance by the pri-mary key or some other defined finder method on the Home interface. This requires a database lookup unless the container has previously cached the primary keys in mem-ory. The container then grabs a free instance of the component from the pool and loads the state from the database through an invocation of the ejbLoadmethod. This must be done before any component-method invocations are processed by the container.

Although instances of Entity Beans can be cached by the container, it is important to note that the container must still load the state at the beginning of every transaction in a clustered environment. Why? Because although the container knows that the state has not changed in this application server instance, it may have changed on any of the other server instances in the cluster. Thus, to be safe, it always loads the state from the database before a client can use the object. Thus, there is very little benefit to be gained from caching with regards to Entity Beans. In addition to this, each remote method invocation must go through RMI and serialize all of the arguments in order to make the method call. Thus, it is recommended that in most cases, Entity Beans be exposed through their local interface and fronted with a Session Bean component. This concept is discussed in detail in the Service-Based Architecture chapter. If the Entity Beans do, in fact, require remote access, they should be designed to be coarse-grained so that it is not necessary to make a large number of remote method calls to the component.

With regards to the timing of the persistence methods, it is partly up to the discre-tion of the container when theejbLoad and ejbStoremethods are invoked, as long as transactional integrity is maintained. However, the normal case and mini-mum requirement is to invoke ejbLoadat the beginning of every transaction and ejbStoreat the end of every committed transaction, although these methods have the potential to be invoked more frequently. Once an Entity Bean is loaded for a client in a transaction, the state of the object may be modified, and it is basically used as a cache until that transaction completes. No other client can use that particular instance unless the state is passivated so that it can be restored to complete the transaction.

This can happen under periods of heavy transaction volume if all of the beans in a given EJB pool are being used. When an Entity Bean is passivated, the state of the bean is temporarily saved either to disk or to the database in order to ensure transac-tional integrity and failover. This is something to look out for when sizing the Entity Bean pools in the container, because the additional I/O can start to really affect the overall application performance under heavy user loads.

As EJB container implementations mature, developers are starting to see more optimized database reads and writes within the CMP engine implementations. This includes optimizing theejbStorelogic so that only modified fields are updated to the database, or else no update at all takes place in the case where no properties have been modified. Many vendors also offer some level of control over the read and write strate-gies the container uses regarding its ejbLoad and ejbStore behavior. These

40 J2EE Best Practices: Java Design Patterns, Automation, and Performance

strategies can be adjusted for particular access patterns such as read-only, read-mostly, and updatable entities. However, the majority of business objects in transactional ap-plications fall into the last category, and thus exhibit the same behavior previously described, in which at least one call toejbLoadandejbStore is required at the beginning and end of every transaction. This minimum pattern of database access is, of course, what you would expect from a transactional application and is the same for objects implemented as regular Java classes.

Figure 2.3 illustrates the behavior of this Entity Bean transaction model for a single client invoking a transactional business method. This diagram represents a simple case. Remember that the Entity Bean could also be a part of a larger transaction already started by a Session Bean or another Entity Bean.

In its optimized form, the Entity Bean transaction model is comparable to the Java business object equivalent in which state is loaded at the beginning of the transaction (ejbLoad) and saved at the end (ejbStore). In nonoptimized or extreme conditions in a clustered environment, Entity Beans can be very database and disk intensive be-cause of the need to manage the free pool and activate and passivate instances in a transactional manner. Other points to consider are that Entity Beans are still fairly heavyweight components and that local interfaces should be used wherever possible to avoid RMI overhead.

If you can model your Entity Beans as coarse-grained components, these issues become less of a consideration, but this has been very difficult to do in practice, espe-cially because Entity Beans using Container-Managed Persistence have a one-to-one object-relational mapping limitation. Most business object interaction also requires multiple method calls. Using only one method invocation takes away many of the Figure 2.3 Entity Bean Transaction Model: Example of Single Client, Single

Transactional Method.

advantages of having a stateful business object. EJB 2.0 has addressed many of these issues with local interfaces, although you still must rely on vendor-specific services or third-party object-relational mapping tools to fully address the persistence issues. The next sections compare the Entity Bean transaction model against that of regular Java business objects.

Java Business Object Transaction Model

The transaction model using regular Java classes as business objects depends on the particular implementation. It does not include declarative transactions on the business object itself, although they can participate in existing EJB transactions, particularly those started by a Session Bean. In general, the Java business object approach uses a similar approach to dealing with business objects within transactions with two notice-able differences:

Instances of Java business objects are not usually pooled; typically, Java objects are instantiated for a particular client from the database to represent an instance of the business entity. Thus, the trade-off is cost of object instantiation versus cost of activation/passivation under heavy user loads.

Java business objects require participation in a Session Bean transaction, whether it is a container-managed transaction or a bean-managed transaction.

In either case, it is recommended to wrap business objects with a Session Bean layer, so there is not much of a trade-off on this point.

Business object persistence within a transaction follows the same pattern under nor-mal circumstances in either option. A business object is either instantiated or grabbed from the pool, and the state of that particular instance is loaded from the database.

Methods are invoked on the business objects, and the state is modified. This can hap-pen for a number of business objects in memory at a time within a transaction. Either at different points along the way or when all of the work is completed, each business object can save its data to the database. As long as the data-access objects or Entity Beans being used share the same data source provided by the application server, the business objects can participate in the same overall transaction. This works for either a container-managed transaction declared by a Session Bean or for a user-managed transaction that is executed specifically in the code. The pattern of using Session Beans to declare transactions and wrap the business objects in a service is explored in detail in the chapter on Service-Based Architecture.

One nice benefit provided by the Entity Bean model is that it has a built-in mecha-nism to handle transaction concurrency. There are different transaction isolation settings that can be used to prevent multiple users from updating the same instance of the same business object at the same time. The strictest setting for Entity Beans, TRANSACTION_SERIALIZABLE, allows only one client at a time to execute a method on a given instance as defined uniquely by the Entity Bean’s primary key. Note that, however, this is also the most expensive setting and that a looser setting is more com-monly used for better performance. A Java business object implementation is required to implement its own mechanism for transaction concurrency, commonly known as locking. This topic is discussed in detail in the next design consideration about handling transaction concurrency.

42 J2EE Best Practices: Java Design Patterns, Automation, and Performance

Overall Comparison of Entity Beans

在文檔中 WILEY advantage (頁 63-67)