Web services provide interoperable application-to-application communication, allowing new applications to leverage existing software functions in a platform independent fashion. The transactional behaviour of a function accessed through a web service depends on the underlying implementation of the web service. Often a database system will provide the required local transactional behaviour. However, when an application combines multiple web services in order to complete a given task, coordination of the participating web services is required in order to preserve data consistency.
Traditionally two phased commit (2PC) based protocols have been used to achieve such coordination (e.g. X/Open DTP, CORBA OTS). Because of the loosely-coupled nature and autonomy requirements of web services, 2PC-based protocols may however not be appropriate in this environment. This could be because of the following reasons:
- The application uses multiple non-extended-architecture (XA) resources.
- The application uses more than one atomic transaction, for example, enterprise beans that have Requires new as the setting for the Transaction field in the container transaction deployment descriptor.
- The application does not run under a global transaction.
This is especially relevent in case of long-running transactions that avoid locks on non-local resources, use compensation to handle failures, potentially aggregate smaller atomic transactions. In contrast to rollback in ACID transactions, compensation restores the original state, or an equivalent, and is business-specific. The compensating action for making a hotel reservation is canceling that reservation, possibly with a penalty.
Interaction between web services, are typically handled through conversational transactions, that involve participation from several web services. The unit of business at each web service represents a subtransaction, also called component transaction.
The transactional behaviour of a single subtransaction is typically provided locally by an underlying database system. Additionally, transactional behaviour of the conversational transaction must be guaranteed through coordination and management of the set of subtransactions. If one or more subtransactions abort, the conversational transaction may or may not need to be cancelled depending on the business logic of the service. It is totally up to the web service starting the conversation to decide if all-or-nothing semantics should be enforced.
Within classical transaction processing, dependent transactions would have to be aborted if the dependent-upon transaction aborted. Resorting to cascading rollback of dependent transactions is however not acceptable in web services, both since dependent transactions may themselves be committed, and also since rollback may be disallowed by autonomous web services. Autonomous web services typically consider the results of a committed subtransaction as final and durable.
Here, the Compensating Transaction enters the stage - to semantically undo the results of the early committed subtransactions. A compensating transaction preserves database integrity without aborting other transactions.
Compensation Transaction -> semantically undoes the partial effects of a transaction T without performing cascading abort of dependent transactions, restoring the system to a consistent state.
The web services designer is responsible for determining the compensation rules, which are used to dynamically generate compensating transactions during runtime.
This can be automated by:
- In BPEL, using invocable Compensating Transaction
- Coordinator protocols like OASIS Business Transaction Processing, and WS-CAF - mediate the successful completion or use of compensation in a long-running transaction.
- Including a Rules Engine (which does on an Event if a Condition satisfied does an Action)
- Custom solution using database as a rules repo(using triggers for events)
Also, read related blogs: