Paul Robinson [
https://community.jboss.org/people/paul.robinson] modified the document:
"Compensating Transactions: When ACID is too much"
To view the document, visit:
https://community.jboss.org/docs/DOC-48610
--------------------------------------------------------------
I'm using this article as a place for the community to review a series of blog posts
I'm preparing.
The plan is to base my JUDCon:Boston talk roughly on this series of blog posts. The code
examples will demonstrate the current design of the compensations API. I'll also be
adding sections at the end of the talk, to explain what we have implemented so far and our
future roadmap; I'm not sure how much of this I will cover in the blog posts. Maybe
I'll have a part 5, that covers this.
h1. Compensating Transactions: When ACID is too much.
h1. Part 1: Introduction
ACID transactions are a useful tool for application developers and can provide very strong
guarantees, even in the presence of failures. However, ACID transactions are not always
appropriate for every situation. In this series of blog posts. I'll present several
such scenarios and show how an alternative non-ACID transaction model can be used.
The isolation property of an ACID transaction is typically acheived through optimistc
[REF] or pessimistic [REF] concurrency control. Neither approach works well if the
duration of the transaction exceeds a few seconds [REF]. This can frequently be the case
for transactions involving slow participants (humans, for example) or those distributed
over high latency networks. Also, some actions can’t simply be rolled back; such as, the
sending of an email or the invocation of some third-party service.
A common strategy for applications that can’t use ACID, is to throw out transactions
altogether. However, with this approach you are missing out on many of the benefits that
transactions can provide. There are many alternative transaction models that relax some of
the ACID properties, while still retaining many of the strong guarantees essential for
building robust enterprise applications. These models are often refered to as
"Extended Transaction models" and should be considered before deciding not to
use transactions at all.
In the Narayana project, we have support for two Extended Transaction models; "Nested
Transactions" and a compensation-based model based on "Sagas" [REF]. In
this series of blog posts I'll be focusing on the compensation-based approach. The
following three posts will each focus on a particular area where compensation-based
transations could prove to be a better fit than ACID transactions. I'll also present
the latest iteration of our new API, that was first introduced in [REF]. In the final part
i'll cover the current status of this API and present the current roadmap for the
outstanding features.
What is a ‘Compensation-based transaction’?
In an ACID transaction, changes are not visible outside of the transaction until it
completes. An atomic outcome is guaranteed using a two-phase protocol in which locks are
obtained prior to the first phase and released in the second phase. The transaction
manager guarantees an atomic outcome, even in the presence of failures.
[TODO: show sequence diagram with locks]
In a compensation-based transaction, changes are visible outside of the transaction as
soon as they are made. If any of the participants are unsuccessful, the transaction
compensates those participants that have already completed their work. This compensation
action is application specific and is required to ‘undo’ the changes made by the
transaction. Similarly to the ACID transaction, the transaction manager guarantees an
atomic outcome, even in the presence of failures.
[TODO: show sequence diagram with locks]
h1. Compensating Transactions: When ACID is too much.
Part 2: Non-Transactional Work
h4. Introduction
[TODO]
h6. Non-transactional work
ACID transactions rely on the work supporting rollback. This is fine for work that
interacts with transactional resources, such as databases or message queues. However
actions like sending an email cannot be rolled back. Here a compensation-based transaction
can be used as an alternative. In this case the compensation action is to send another
email notifying the recipient of the final outcome.
Alternatively, you may have multiple XA (two-phase) aware resources, but due to
performance reasons you need to run them in one-phase mode.
Maybe you have a combination of transactional and non-transactional work. In this case the
transactional work can be rolled back, if required, whilst the non-transactional resources
are compensated.
Also, you may have transactional resources or services, but, for whatever reason, they
will not participate in an existing transaction. This can occur when you try to compose
multiple services outside of your control. For example, a travel agent application may
compose a transaction of calls to third party services. Providing these services offer an
interface for cancelling (compensating) a booking, you should be able to use a
compensation-based transaction to coordinate them.
If you find yourself needing to coordinate multiple non-transactional tasks, you should
consider using compensations.
h1. Compensating Transactions: When ACID is too much
Part 3: Cross-Domain Distributed Transactions
h3. Introduction
[TODO]
When your application becomes distributed, you greatly increase the chances of failure.
Many of these failures can be tolerated by using a distributed ACID transaction. However,
this approach is often dismissed as impractical for a number of reasons.
The first is that distributed transactions tend to take longer to run, due to the
increased communication latency. This can cause big problems for your throughput as the
duration of held locks greatly increases.
The second issue is that all the servers in the distributed transaction become
tightly-coupled. Furthermore, the server that begun the transaction has full control over
when the transaction should complete (ignoring the option of making a heuristic decision,
which is really bad!). This may be acceptable if all the servers reside in the same
business domain, but it’s rarely acceptable for cross-business domain applications.
Compensation-based transactions can be used to solve both of these problems. The latency
imposed by the distributed transaction does not result in holding of locks for extended
periods as the work is completed immediately, rather than waiting until the end of the
transaction. If this work was a database update, it would be committed immediately. A
second database update would be made to undo the change, should compensation be required.
Compensation-based transactions also encourage a loosely-coupled architecture as each
participant offers a more natural interface to the coordinator. For example, in a flight
booking example, the service interface would consist of ‘bookFlight’ and ‘cancelFlight’
operations (‘cancel’ being the compensating action).
h1. Compensating Transactions: When ACID is too much
Part 4: Long Lived Transactions (LLT)
h3. Introduction
[TODO]
h6.
ACID transactions are not particularly well suited for transactions that take a long time
to run. This is because they acquire locks on resources as they progress and don’t release
them until the transaction completes. In the meantime, other transactions, requiring that
data, are blocked. Furthermore, a failure of a long running transaction results in the
loss of all work completed so far.
A compensation-based transaction can be composed of multiple short-lived ACID
transactions. When each transaction completes, it releases the locks on the data it held,
allowing other transactions, requiring that data, to proceed. A compensation action is
registered for each ACID transaction. These actions are invoked, in reverse order, for all
completed transactions, should the LLT need to be aborted.
Furthermore, should one of these short-lived transactions fail, it could be possible to
find an alternative, preventing the entire transaction from failing, and allowing forward
progress to be achieved. Also, in some situations, as the transaction progresses, you may
decide to abort just part of the transaction.
For example, take a travel booking example. We begin by booking a flight. We then try to
book a taxi, but that fails. At this point we don’t want to compensate the flight as it
may be fully-booked next time we try. Therefore we try to find an alternative Taxi, which
in this example succeeds. Later, in the LLT, we may find a cheaper flight, in which case
we want to cancel the original flight whilst keeping the taxi and booking the cheaper
flight. In this case we notify our intentions to the transaction manager who ensures that
the more expensive flight is compensated when the LLT completes.
h6. Conclusion
In this blog post I’ve introduced the concept of a compensation-based transaction and
showed how it could be used to provide strong guarantees in situations that are not
applicable for ACID transactions.
Most of what is discussed here is already supported through our WS-BA implementation. We
are currently in the process of decoupling this technology from Web Services and improving
the developer API.
--------------------------------------------------------------
Comment by going to Community
[
https://community.jboss.org/docs/DOC-48610]
Create a new document in JBoss Transactions Development at Community
[
https://community.jboss.org/choose-container!input.jspa?contentType=102&a...]