InformIT

Transaction Processing in Distributed Service-Oriented Applications

Date: Nov 24, 2004

Return to the article

The ACID transaction model has served the industry well in the past, but Jon Maron points out that it has some major drawbacks when applied to the loosely coupled service domain.

Transaction processing has always been at the core of data-driven enterprise applications. However, the prospect of creating transactional applications was daunting and initially viewed as the province of a select group of highly specialized developers. Therefore, various products, APIs, and platforms evolved over the years to shield a developer from the underlying complexity. The Java platform provides a classic case study of this evolution.

Since the release of JDBC, the first Java-based resource management API, the Java platform has provided the facilities for the demarcation of transactional work. Initially, these facilities simply provided the ability to perform transactional work while leveraging a single database. However, with the release of the Java 2 Enterprise Edition (J2EE) platform and the associated JDBC XA specification interfaces, developers were able to programmatically—or, in the case of Enterprise Java Beans (EJB), declaratively—specify the boundaries of a distributed transaction.

However, with the introduction and growing popularity of service-oriented architectures (SOA) the underlying transactional mechanisms from which the developer has been shielded have become much more relevant. The loosely coupled nature of distributed service applications in many cases breaks some of the essential assumptions of existing transaction-processing systems and shifts some of the burden of transaction management from the core infrastructure to the actual service developer.

This article explores the two-phase commit protocol, explains its limitations with respect to distributed service architectures, and describes some of the characteristics of the evolving service-oriented transaction standards aimed at providing data consistency across a distributed service-oriented application.

Two-Phase Commit

The fundamental goal of transaction processing platforms is to guarantee that work performed across multiple distributed components within a system can execute atomically ("all or nothing" semantics), in isolation from other elements in the system, and can be recorded permanently on some form of durable media. These characteristics are collectively referred to as the ACID properties of a transaction—atomicity, consistency, isolation, and durability. Achieving this goal requires that the leveraged resource managers (such as databases) reach a consensus about whether it's appropriate to make permanent and visible the work each performed during the execution of the transaction. This goal is most commonly achieved by using the two-phase commit protocol.

Once an application has completed its work across multiple distributed databases, it can issue a commit request that initiates the termination (two-phase commit) protocol.

NOTE

Although other resources such as JMS providers can participate, we'll focus on databases for this discussion.

During the initial (prepare) phase of the protocol, a transaction coordinator sends out a "prepare" message to all databases that have enlisted in the transaction, requesting that each database indicate its readiness to commit or roll back the work managed in the scope of the given transaction. For their part, the databases attempt to checkpoint their work and obtain locks for the affected records and, if successful, respond with a vote to commit. Otherwise, they issue a vote to roll back the transaction. The coordinator proceeds with the second (commit) phase only if all databases have voted to commit. During this phase, the coordinator issues the appropriate command (commit or roll back) to all databases and records the result of the transaction (see Figure 1).

Figure 1Figure 1 Two-phase commit protocol.

It's important to note that the two-phase commit protocol is a blocking protocol. (Hint: This will be critical to our discussion of service-oriented transactions.) Once a resource manager receives the prepare message and replies with a commit vote, it's obligated to lock the relevant records or data until the coordinator communicates an outcome during the second phase. During this period, a resource manager is said to be "in doubt" or "uncertain." In addition, the protocol message exchanges occur between a transaction coordinator and resource vendor–provided implementations of the XA resource interfaces; the running application is oblivious to the process it has triggered by requesting a commit of the distributed transaction.

Now that you have a basic understanding of the two-phase commit protocol and some of its underlying mechanisms, let's explore its applicability in a service-oriented architecture.

Transactions and Web Services

Most service-based or business-to-business (B2B) applications would like to have the data consistency and correctness guarantees provided by existing transaction-processing platforms. Unfortunately, achieving these goals is difficult because interactions between the participants may be complex—involving multiple parties, spanning different organizations, and, most notably, lasting for hours or even days. For example, a transaction for a computer parts ordering application may involve different suppliers and may not be complete until all parts have been delivered. Should the various suppliers block part requests until this transaction is complete? Multiple reasons prevent such services from locking their back-end data resources for long durations: for example, the inability to service additional incoming requests, and the potential for enabling denial-of-service attacks.

Therefore, web service transaction implementations must provide a framework that essentially "loosens" the ACID properties associated with the standard two-phase commit protocol. In effect, a web service transaction should compose the various participants into one or more consensus groups such that all members of a given group have the same result. All of the services in a transaction may not necessarily belong to the same consensus group, and the business transaction can selectively commit a subset of services while other services are rolled back.

Consider a travel application that can book a flight, rent a car, and purchase travel insurance (see Figure 2). A user of this application initially books an airline ticket and reserves a rental car. Given that neither of these two actions should occur independently, the two services are assembled into one consensus group; if either of these services fails to execute, both participants will roll back. However, once the user proceeds to the travel insurance purchase, he may want to obtain multiple quotes. Each quote can be handled within its own consensus group, thus allowing the user to actually purchase a quoted policy in order to reserve the price—but subsequently cancel (roll back) the purchase if another travel insurance service provides a lower quote.

Figure 2Figure 2 Service-based travel application.

But the consensus group construct solves only part of the problem. While consensus groups allow the web services transaction coordinator to identify a core set of services required for the successful completion of the transaction, they don't address the responsibilities of the services as transactional participants. Recall that in a standard transaction-processing system, the transaction coordinator interacts with resource managers, such as databases, to achieve a consensus. However, in the services domain the services are effectively acting as the resources (either directly or via a registered participant provided by a web services transactioning infrastructure implementation); ultimately, the services in some way respond to transaction-demarcation requests from the coordinator.

Thus, a service within a distributed business transaction may need to support provisional or tentative state changes during the course of a transaction. Rather than thinking in terms of "prepare" and "commit" phases, a service may actually support the completion of a business transaction by either "confirming" or "canceling" the work executed; when asked to cancel, or compensate, the service must undo the work it performed.

For example, in our travel application example, once the user has elected to purchase a travel insurance policy, the relevant service may actually commit the purchase information and record it in a back-end database; the back-end resource is not locked for any significant period of time and other quote requests can be fulfilled by the service. However, if in the course of the overall business transaction the user subsequently cancels the purchase, the service will have to perform a compensating action such as executing another transaction to remove the purchase data from the database. Clearly, the responsibilities of a transactional service are more significant and require more thought and planning than in a traditional, single-process application.

Now that we've established the unique aspects of long-running business activities, let's examine the architectural elements required to support web services transactions.

Web Services Transaction Architectures

Most web services transaction protocols build on the existing concepts of a transaction coordinator, participants, and a transaction context (see Figure 3). The general concepts behind these protocols are analogous to those of traditional transaction systems.

Figure 3Figure 3 Web services transactions.

As the figure indicates, the application interacts with the coordinator in some fashion (the specifics are unique to the transaction protocol utilized) to initialize a transaction and create an associated transaction context; the transaction context is propagated between the clients and the services, providing a flow of context information required to identify a transaction with which work should be associated (as well as the location of the coordinator). The propagation of the context may occur transparently to the client and services.

Components of the web services transaction system are responsible for propagating the context whenever a client contacts a service whose work it wants as part of the transaction. When a service receives an invocation accompanied by a transaction context, it has to register a participant (possibly itself) with the referenced transaction. Subsequently, the transaction coordinator ultimately controls the work performed by the participant. Thus, the roles of coordinator and participant are actually rather similar to those defined in traditional transaction-processing systems.

Conclusion

Web service based architectures present significant challenges to achieving consistent outcomes from long-running business activities. Whereas the pure ACID transaction model has served the industry well in the past, it has some major drawbacks when applied to the loosely coupled service domain. However, protocols are evolving that will yield the same reliable outcomes we have grown to expect from traditional transactioning systems.

800 East 96th Street, Indianapolis, Indiana 46240