Transactions in SOA
This short article looks at options available for implementing transactional behaviour in service oriented systems.
What is a Transaction?
In modern systems, with data and processing distributed across numerous physical nodes, transactions are one of the ways of co-ordinating data and processing into a single 'unit of work' that either succeeds or fails together. This is done to ensure that the data is always in a consistent state across the whole system. The traditional example of this approach is a bank transfer, where you want the money to be taken from account A and placed into account B, or not to be taken from account A and not placed into account B. Transactions are often referred to as having the ACID properties, that is, Atomic, Consistent, Isolated and Durable.
Java EE has standards based interfaces (JTA) for the demarcation and management of transactions, with in an application and across application or system boundaries.
Due to their universal availability in application servers, transactions get used for different purposes in different applications, in some cases, end-to-end, guaranteed, data consistency is the goal, wheras in other systems the objective is guaranteed delivery and processing. In these situations, it is only a subset of the ACID properties that are required by the applicaiton, but the ease of configuring a fully ACID transcation means that it is easier to obtain them all.
Transactions in SOA
Using a Service Oriented Architecture introduces a number of challenges when dealing with operations that need to occur in a transactional manner. SOA Best practices encourage the use of asyncronous services, which do not mix well with the tight coupling used in transactional systems. In addition, while there are a number of protocol-level technologies available for transactional behaviour, there are no standards or technologies for end-to-end transactions in an SOA system. In addition, existing technologies for describing the interfaces between components in an SOA system do not have nice ways of describing the transactional behaviour of operations.
There are a number of techniques used to obtain transaction-like behaviour in service oriented systems, but before chosing an approach, or combination of approaches, it is important to understand exactly what the desired behaviour is, and which of the ACID properties are required in the particular application use-case.
Protocol level approaches
Using a transaction technology provided by the transport protocol, such as WS-Coordination, and other associated web services standards, can go some way to providing the desired behaviour, but there are limited integrations between these standards and SOA products such as ESBs. WS-Coordination is a technology that allows a number of web-services to come to an agreed decision regarding the outcome of an operation, and provides the building block for a number of transaction related web services standards, such as WS-Atomic Transaction and WS-BusinessActivity. Support for these standards in ESBs and other SOA technologies is currently very weak, but as SOA appraoches gain market share, we may see the support for these standards becoming more common, until then, these technologies do not provide a good method of implementing transactional behaviour.
For situations where only guaranteed message delivery/processing is required, then depending on the characterstics of the processing pipeline, using a reliable/transacted delivery protocol (such as JMS) can be enough. When doing this, you are relying on the transactional behaviour of the protocol though, and must ensure that it is configured for the correct behaviour.
Compensating Operations
The most common approach used to provide 'transaction like' behaviour to service oriented systems, is the use of compensating operations. In this approach, each operation that modifies state has a corresponding operation to undo that modification. The orchestration level on top of the services then needs to check that all operations succeeded. If an operation failed, the orchestration level should call the copensation operations on each service that did not fail.
This approach relies on the developers of the services and orchestration layers to specifically code for transactional behaviour, and can therefore be seen as a step backwards from the declaritive transaction demarcation that enterprse developers are used to. However this appr oach ensures that the behaviour is as expected, and in my view, having developers think explicitly about required transaction behaviour is no bad thing.
Conclusion
While there are a number of standards for transactions at the protocol level, no overarching standard has emerged at the SOA level. For this reason, the compensating operation approach is the most common approach seen in the current generation of service oriented systems, and while it is a more manual approach than declaritive transaction demarcation, having developers think about the desired transactional behaviour is not necessarily a bad thing.