It seems that every new technology brings an associated set of buzzwords; marketing departments love it when they can tout the latest buzzwords in their product, whether or not they know what those terms mean. The following sections look at the buzzwords surrounding Enterprise JavaBeans and describe what they really mean to your enterprise solution.
Transactions involve the grouping of sets of actions under the umbrella of a single atomic operation; these actions can include the addition of data, removal of data, or modification of data in a database that spans multiple tables, as well as interaction with non-database resources.
As an example, consider transferring $100 from your savings account to your checking account:
Withdraw $100 from your savings account.
Deposit $100 to your checking account.
If you successfully withdraw $100 from your savings account and then the computer system crashes before it can deposit the $100 into your checking account, what happens? If the deposit cannot occur, you don't want the withdrawal to be committed; you only want the withdrawal to occur if the deposit succeeds. Likewise, if you're the bank you don't want the deposit to be committed unless the withdrawal succeeds.
We can group both of these actions into a single transaction and call that operation a single atomic action. If the withdrawal succeeds and the deposit fails, the entire transaction is "rolled back" and the system is restored to the same state it was in before the transaction started.
Transactions can be far more complicated than this, including multiple database calls as well as non-database resources.
Distributed object architectures such as EJB are designed to make an object on one computer appear as though it's running on another computer. As a developer, you communicate with a component on another computer as though it's on your computer, and the underlying architecture handles all the network code to locate the component, forward your local request to it, gather the response from it, and forward the response to you. Figure 3 shows how this works:
The client sends a method request to a stub.
The stub converts the request into data that it can transport across the network (this process is called marshalling).
The stub forwards the request to the proxy running on the server machine.
The proxy unmarshals the request.
The proxy calls the server's method on behalf of the client.
The proxy receives the result of the server call.
The proxy marshals the results.
The proxy returns the results to the stub.
The stub unmarshals the response.
The stub returns the results to the client.
As you can see, this is a complicated task that's better left for someone else with communication expertise to implement on our behalf; furthermore, if it's done in a standard way, we can communicate with other components that we didn't necessarily write.
The big hype that surrounded Java when it was first announced was its claim to be platform-independent. True to its claim, Java is platform-independent! The way Java accomplishes this is that all of its code is compiled into an intermediate code known as bytecode. This bytecode is then interpreted by a virtual machine that's implemented in a native programming language that translates the code into its platform-dependent equivalent. As long as a Java Virtual Machine is implemented for a platform, compiled Java code can be executed through that virtual machine on that platform.
EJB is not the only technology that provides many of the features I'm talking about, but the closest competitor is Microsoft's DCOM/COM+ technology running in the context of Microsoft's Transaction Server (MTS). DCOM/MTS provides a powerful programming paradigm, but it's limited to running on Microsoft Windowsbased platforms. Java, on the other hand, can run on powerful UNIX machines (Sun Solaris, HPUX, AIX, and so on) as well as Microsoft Windowsbased platforms. This provides a higher degree of interoperability and portability.
Scalability refers to the growth of a system in two directionsvertical and horizontal:
Vertical scalability refers to deploying a single, powerful machine that supports multiple users and a higher throughput. EJB application servers can be configured to use multiple CPUs and the power of a larger computer system effectively.
Horizontal scalability refers to deploying multiple application server instances on multiple machines that run in parallel and share the processing load; this is sometimes referred to as clustering. Some EJB application servers offer horizontal scaling; most of the commercial solutions support it, while most of the Open Source solutions don't as of yet.
Developing code to scale in this fashion is quite an endeavor, best left to the experts in this area!
Portability refers to transferring a component from one brand of application server to another. Initially this was a difficult task, but it's progressively getting better. As long as an EJB application server adheres to a specific version of the EJB standard, transferring a bean from one application server to another is a simple matter of modifying the application-server-specific deployment descriptors.
The Enterprise JavaBeans specification was developed to allow all code and a global deployment descriptor to be written standard across the boundaries of an application server. The final step in deploying an EJB on an application server is the mapping of resources from the standard deployment descriptor to their application server equivalents. For example, if your EJB wants to access a database connection pool in a specific manner, you must tell the application server to present the database connection pool in such a way that the EJB can access it.
High portability is essential in this market space; if you must redevelop your code for each application server on which your code will be deployed, it defeats the purpose of using a standard. Like any technology, early adopters (mid-1999) experienced difficulties migrating between application servers, but in today's playing field the changes are minimal.