Transactional middleware is not a new concept. It originated back in the days of the mainframe, at a time when most mainframe databases came with transactional middleware. These were, in fact, TP monitors that managed processes and coordinated access to the database. To work, transactional middleware requires that complex applications be divided into bite-sized units called transactions. Transactional middleware controls transactions from their beginning to their end, from the client to the resource server and then back again. In these scenarios, transactions are either all or nothing. Either they work or they do not. A transaction is never left incomplete. As a result, transactional middleware always leaves the system in a stable state. This provides the developer with a consistent and reliable programming model. This stability also makes transactional middleware a natural choice for distributed applications, which must deal with many different databases, queues, and batch interfaces running on heterogeneous platforms (see Figure 7.2). Figure 7.2. Using transactions to tie together back-end resources.The ACID TestBefore delving too deeply into transactional middleware, we must clearly understand the concept of transactions. An easy way to remember the properties of a transaction is to put it to the "ACID" test. That is, a transaction has ACID properties if it is Automic, Consistent, Isolated, and Durable. Automic refers to the all-or-nothing quality of transactions. Either the transaction completes, or it does not. There is no available middle ground. Consistent refers to the fact that the system is always in a consistent state, regardless of whether or not it completes the transaction. Isolated refers to the transaction's ability to work independently of other transactions that may be running in the same TP monitor environment. Durable means that the transaction, once committed and complete, can survive system failures. Although the ACID test might oversimplify the concept of a transaction, it provides an easy acronym for remembering the features and functions of transactional middleware. Developers can count on a high degree of application integrity with transactional middleware even in heterogeneous environments of very different operating systems and databases. The most important benefit of transactional middleware is that a transaction is always secure. Even when other things go wrong, transactional middleware won't allow those problems to affect any other transaction, application, or data. Scalable DevelopmentTransactional middleware processes transactions on behalf of the client or node. It can route transactions through many diversified systems, depending on the requirements of the application integration problem domain. For example, it is not unusual for a TP monitor to tie together a mainframe, an NT server, a multiprocessing UNIX server, and a file server. Transactional middleware also provides load balancing, thread pooling, object recycling, and the ability to automatically recover from typical system problems. All of this allows this type of middleware to scale to a transaction load that will drive even the largest businesses. Although transactional middleware is correctly though only technically referred to as middleware, it is much more than a simple middleware connection layer. It provides a location for the application code to run and, as a result, a location for business processing and application objects to run. It is also a location where application services can be shared among applications. Transactional middleware can be used to enforce business rules and maintain data integrity, or to create entire applications by building many transaction services and invoking them from the client. Database MultiplexingOne of transactional middleware's great benefits is its ability to multiplex and manage transactions, thereby reducing the number of connections and processing loads that larger systems place on a database. With transactional middleware in the architecture, you can increase the number of clients without increasing the size of a database server. For example, by using a TP monitor requiring approximately 50 connections, more than 1,000 clients can access the database server. By "funneling" client requests, transactional middleware removes the "process-per-client" requirement (see Figure 7.3). In such a scenario (also known as database connection pooling), a client simply invokes the transaction services that reside on the TP monitor, and those services can share the same database server connections (threads and processes). If a connection overloads, the TP monitor simply starts a new connection to the database server. This is the foundation of three-tier architecture and the explanation for how three-tier architecture can scale to high user loads. Figure 7.3. Database multiplexing.Load BalancingLoad balancing happens when the number of incoming client requests surpasses the number of shared processes the system is able to handle and other processes start automatically. Some transactional middleware can dynamically distribute the process load over several servers at the same time or distribute the processing over several processors in multiprocessing environments. The load-balancing features of transactional middleware enable it to define "classes" of tasks and therefore prioritize tasks. This capability assures VIP clients of top-notch service. High-priority classes kick up the process priorities. As a rule, developers use high-priority server classes to encapsulate short-running, high-priority functions. Low-priority processes (such as batch processes) run inside low-priority server classes. Developers can also assign priorities by application type, the resource managers required by a transaction, high and low response times, or the fault tolerance of a transaction. By defining any number of parameters, developers can control the number of processes, or threads, available for each transaction. Fault ToleranceTransactional middleware was built from the ground up to provide a robust application deployment environment with the ability to recover from any number of system-related problems. Redundant systems guarantee high availability. For example, transactional middleware uses dynamic switching to reroute transactions around server and network problems. The transactions work through a two-phase-commit process that ensures that the transactions complete and guards against transactions becoming lost electrons when hardware, operating systems, or networks fail. Two-phase commit also ensures that reliable transactions can be performed on two or more heterogeneous resources. If the power fails, transactional middleware alerts all participants in a particular transaction (server, queues, clients, etc.) of the problem. All work accomplished up to that point in the transaction is rolled back, and the system returns to its "pretransaction" state, cleaning up any mess it may have left. Developers sometimes build transactions that automatically resubmit after a failure. The ability to create an automatic-resubmit feature is highly desirable in the context of an application integration problem domain because transactional middleware ensures delivery of the information being shared by the source and target applications. This beneficial feature has not escaped the notice of message broker vendors. Many vendors are now working to provide transactional integrity in their products. CommunicationTransactional middleware is a good example of middleware that uses middleware, including message brokers. Transactional middleware communicates in a variety of ways including RPCs (specialized for transactional middleware and called transactional RPCs, or TRPCs), distributed dynamic program links (DPLs), interprocess communication, and MOM. Because transactional middleware is simply an API within an application, developers have the flexibility to mix and match a variety of middleware layers and resource servers to meet the requirements of an application or application integration problem domain. |