The Role of Performance in Design

   

Minimizing Remote Calls

The primary performance concern associated with a distributed architecture such as EJB is the amount of network traffic it requires. When a remote client makes a call to an EJB there's a certain amount of overhead involved. Part of this is just the time it takes to move data between the client and the container across the network. You also have the impact of the transaction and security processing that takes place when the container receives a client request. You can't get away from this overhead completely because it's part of the price you pay for the benefits of a distributed application. However, you should be conscious of the number of calls a remote client is required to make to do its work. As you've seen in earlier chapters, EJBs that are designed with remote clients in mind serve their purpose best when they're coarse-grained. When an EJB is designed to provide significant business logic or workflow management to a client, its overhead is easier to justify.

Even when an EJB is coarse-grained in terms of the functionality it provides, you still need to watch the number of calls you make to it. This point is easiest to illustrate with an entity bean that has quite a few attributes.

Note

As mentioned in previous chapters, entity beans are normally accessed through a local interface. However, there might be circumstances where you need to expose an entity bean to remote clients instead. For example, if a session bean were deployed in a separate JVM or on a different node in a cluster from an entity bean, it would need to use a remote interface to access that entity. A local interface can only be used for EJBs deployed in the same JVM.


The EnglishAuctionRemote interface that was first introduced back in Chapter 6, "Bean-Managed Persistence," exposes a number of get and set methods such as those shown in the following subset of the interface:

 ...    public void setName(String newName) throws RemoteException;    public String getName() throws RemoteException;    public void setDescription(String newDescription) throws RemoteException;    public String getDescription() throws RemoteException;    public void setStartingBid(Double newStartingBid)      throws InvalidAuctionStatusException, RemoteException;    public Double getStartingBid() throws RemoteException;    public void setMinBidIncrement(Double newMinBidIncrement)      throws InvalidAuctionStatusException, RemoteException;    public Double getMinBidIncrement() throws RemoteException;    public void setReserveAmount(Double newReserveAmount)      throws InvalidAuctionStatusException, RemoteException;    public Double getReserveAmount() throws RemoteException;    public void setStartDateTime(Timestamp newStartDateTime)      throws InvalidAuctionStatusException, RemoteException;    public Timestamp getStartDateTime() throws RemoteException;    public void setScheduledEndDateTime(Timestamp newScheduledEndDateTime)      throws InvalidAuctionStatusException, RemoteException;    public Timestamp getScheduledEndDateTime() throws RemoteException;  ... 

Methods such as these are no problem when declared in the EnglishAuction local interface because the overhead of each call from a local client is relatively small. You can't say the same for using these methods in a remote interface, though. The problem with exposing fine-grained access to individual attributes like this is that a remote client that needs to read or modify multiple attributes has to make several calls on a bean's remote interface to do its work. You might not want to get rid of this fine-grained access because sometimes only a single attribute needs to be accessed. What you want to do instead is provide alternative get and set methods that work with a data structure that holds multiple attributes of a bean. If you can provide a client what it needs with fewer remote calls, the amount of time spent accessing a bean is sure to drop. Listing 17.1 shows an example class that bundles multiple attributes of the auction entity bean together.

Listing 17.1 EnglishAuctionSnapshot.java “A Snapshot Data Object for an Auction Entity Beanpackage com.que.ejb20.auction.model;
 /**   * Title:        EnglishAuctionSnapshot<p>   * Description:  Data object for an auction entity bean<p>   */  import java.sql.Timestamp;  import java.io.Serializable;  public class EnglishAuctionSnapshot implements Serializable {   public Integer id;    public String name;    public String description;    public String status;    public Double startingBid;    public Double minBidIncrement;    public Double reserveAmount;    public Timestamp startDateTime;    public Timestamp scheduledEndDateTime;    public Timestamp actualEndDateTime;  } 

The first thing to notice about EnglishAuctionSnapshot is that it looks more like a C/C++ struct than a Java class. This simplicity in the declaration of the class is intentional. The only purpose of a class like this is to pass data. The absence of any methods (including get and set methods) makes it clear that there's nothing to an EnglishAuctionSnapshot object other than the data it holds. It's referred to as a snapshot here because you can think of it as a snapshot view of an entity bean's state at a particular instant. It's of no value once the state of the entity changes. You'll also see a class like this commonly referred to as a data object .

A snapshot class becomes useful when you add methods like the following to the remote interface (and implementation) of an entity bean:

 public EnglishAuctionSnapshot getSnapshot() throws RemoteException;  public void setFromSnapshot(EnglishAuctionSnapshot ss) throws RemoteException; 

The idea is that a client that needs access to multiple attributes of an entity object can call its getSnapshot method instead of the individual get method for each attribute. An entity bean class implements this method simply by creating a new snapshot object and loading it with its current attribute values. The setFromSnapshot method is meant to provide the opposite capability by performing the equivalent of multiple set method calls with a single remote call. You might have noticed that EnglishAuctionSnapshot was declared to implement Serializable . This is necessary for a snapshot object to be used as a return value or method parameter in a remote interface.

The example shown here includes all the attributes of the associated entity bean in the snapshot class, but it might also make sense to declare other snapshots that hold subsets of attributes that are commonly used together. This should be a secondary concern to you though. What's more important is to go ahead and define at least one snapshot for an entity bean class. You'll find in most cases that retrieving a snapshot with a reasonable number of attributes is faster than making even two calls to individual get methods. Even if the snapshot holds attributes that a particular client doesn't need, the time spent building and passing the complete structure can easily be made up by avoiding other remote calls.

Note

Earlier examples made use of view classes to return a copy of an entity object's state to its clients. The major difference between those classes and the concept of a snapshot is intent. View classes represent objects that are used to communicate with clients outside the application tier . The auction example included the creation of view objects by the auction entity bean, but views are often manipulated only by session beans. A snapshot class exists solely for performance advantages when you're supporting remote clients of your entity beans. Depending on your particular application, you might be able to satisfy your need for a snapshot by reusing an existing view class. Otherwise, you can return a snapshot to a remote session bean and allow it, or a helper class, to create a view based on the data in the snapshot.




Special Edition Using Enterprise JavaBeans 2.0
Special Edition Using Enterprise JavaBeans 2.0
ISBN: 0789725673
EAN: 2147483647
Year: 2000
Pages: 223

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net