1. Problem
You have separate tasks to
accomplish in an orchestration that must all succeed or fail together.
These tasks may take a long time to complete.
2. Solution
Long-running transactions can
help ensure a single consistent outcome across multiple BizTalk tasks.
As an example, suppose you have a web site where customers can make
purchases using credit. Creating a new customer involves two steps.
First, the customer needs a login to access your web site. Second, the
customer also needs credit established to make purchases. Sometimes,
your web site cannot create a login because the customer has chosen a
login already assigned to another customer. Other times, BizTalk cannot
establish credit for the customer. If one of these tasks succeeds and
the other fails, the user may experience undesirable behavior on your
web site.
By defining actions to
reverse each of the two tasks required in this example, BizTalk can
automatically reverse the effects of one task in the event that the
other fails. If BizTalk creates a login but cannot establish credit, it
will detect the failure and invoke the compensation logic to disable the
login. If credit is established but BizTalk cannot create the login, it
will invoke the compensation logic to suspend credit.
The following steps demonstrate how to set up a long-running transaction for this example.
Create a new BizTalk project, and add an orchestration.
Right-click the orchestration design surface, and select Properties Window.
Set the Transaction Type property to Long Running.
Place a Receive shape on the design surface with the Activate property set to True. Configure BizTalk to receive a NewCustomerMsg message.
Place a Parallel Actions shape under the Receive shape.
Place a Scope shape under the left branch of the Parallel Actions shape.
Select the icon in the upper-right corner of the Create Login shape, and select Long Running from the menu, as shown in Figure 1.
Place a Send shape inside the Scope shape.
Set the Send shape's Message property to NewCustomerMsg.
Create a one-way send port named CustomerActivation.
Set the CustomerActivation send port's Delivery Notification property to Transmitted.
NOTE
Use delivery
notification to determine if a delivery failure occurs. BizTalk will not
complete the long- running transaction until the messages with delivery
notification are successfully delivered and will report an error if any
of the messages are suspended.
Right-click the top portion of the Scope shape, and select New Compensation Block from the context menu, as shown in Figure 2.
Place
a Send shape inside the compensation block, and attach it to a new
port. This defines the actions to reverse the transaction if another
transaction fails.
Repeat steps 6 to 13 to define the Create Credit Account scope.
Deploy the orchestration and bind the ports to file locations. To simulate delivery failure to the CustomerActivation and CreditApplication ports, deny the BizTalk Application Users group access to the file locations bound to the orchestration ports.
3. How It Works
The goal of a transaction
is to ensure that many separate tasks will all either succeed or fail
together. With long-running transactions, BizTalk performs each task
independently. If one task fails, then BizTalk must roll back the
changes of the successful tasks. Rolling back successful tasks because
of another's failure is called compensation.
A BizTalk orchestration can determine when successful transactions need
to compensate for a failed transaction, but the BizTalk developer must
define the specific compensation logic.
The solution's example
consists of two tasks, each with custom compensation logic defined. If
BizTalk cannot establish credit for the customer, the Create Login
transaction must compensate by taking actions to disable the login.
Similarly, BizTalk compensates the Create Credit Account transaction by
taking action to rescind credit. BizTalk will detect the error in the
Create Credit Account transaction and call the compensation logic of all
the long-running transactions in the same scope that have completed
successfully. If the Create Login transaction also fails, then both
transactions arrived at the same result, and BizTalk has nothing to
compensate for. BizTalk will compensate only long-running transactions
that complete successfully.
Long-running transactions are a great way to ensure a consistent outcome under circumstances such as the following:
Tasks take longer than a split-second to complete.
Results can be inconsistent for a short while before the compensating logic completes.
BizTalk
needs to send or receive messages with a transport that cannot
participate in an atomic transaction, like an ASMX web service.
In addition to long-running
transactions, BizTalk scopes can also support atomic transactions. An
atomic transaction differs by locking all the resources involved until
the transaction knows they can all succeed. If they cannot all succeed,
the transaction reverses all changes before releasing the resources.
Because of this locking behavior, atomic transactions should be very
quick. A long-running transaction executes each task separately and
follows up with compensating logic if one task encounters an error. This
approach allows separate tasks to have different results for a short
time while the compensating logic executes but also allows greater
processing flexibility.