Long-Lived and Nested Transactions

Long-lived and nested transactions extend the notion of transactions to application processes that can tolerate lower levels of isolation in return for transaction concurrency and throughput for the long-lived operations.

In the previous example shown in Figure 13.11, you could change the properties of the transaction shape TxnGetDoc (shown in Figure 13.13 ) from Short-Lived, DTC-Style to either Timed Transaction or Long-Running. Notice then that you can no longer specify the Isolation Level. If you attempt to run the resulting schedule, you will also notice that there is in fact no DTC style transaction flowing through to the AdvOrchTxn.CAbortTxn component—the schedule just completes. To abort a long-running (or a timed) transaction, you would typically use the Abort shape or return a nonzero HRESULT from a component connected to a COM port.

Look at the following example using nested and long-running transactions. In this example, you also see the On Failure of <Transaction> and Compensation for <Transaction> pages used. Note that the messaging process is not complicated. The contrived business process is to set up a cellular phone tower, shown in Figure 13.16.

Figure 13.16. Business process for NestedTxn.Skv.


In Figure 13.16, the outer, long-running, transaction is called Setup Cell Tower. There are three actions to perform: buy a pole, dig a hole, and set up the cell tower. This example uses the two COM components, AdvOrchTxn.CAbortTxn and AdvOrchUtil.CMsg, developed in previous examples. To construct the schedule, follow these steps:

1.
Set down an Action shape and set the name property to Buy pole.

2.
Drag a Transaction shape over the Action shape so that it completely encloses it. Double-click the Transaction shape and change the name to BuyPole. Set the retry count to zero. This is a short-lived transaction.

3.
Repeat the steps 1 and 2 for the next action (named Dig hole) and its enclosing transaction (named DigHole).

4.
Add the last action shape and name it Set up tower.

5.
Enclose the last action, added in step 4, and the other two transactions in an outer, long-lived, transaction, called Setup Cell Tower. To do this, drag the transaction shape onto the drawing surface, making sure that it does not overlap any other shape. Then, change the shape of the transaction rectangle into a thin, tall rectangle, positioned to the left of the other two transaction shapes. Make this rectangle tall enough to encompass the vertical range of the transaction and action shapes that you want to enclose. Finally, drag the rightmost vertical side of the rectangle over the shapes to enclose.

6.
Open the properties of the BuyPole transaction. Click both the buttons to add code for failure and compensation.

7.
Open the properties of the DigHole transaction. Click only to add code for failure. The reason compensation code is not defined is that, at least for our contrived example, if the DigHole transaction succeeds, the overall transaction will always succeed, and we never have to run a compensation for it.

8.
Add the port implementations using code already developed. Refer to Listing 13.1 for the AdvOrchUtil.CMsg class and Listing 13.7 for the AdvOrchTxn.CAbortTxn class. Make sure that these classes are compiled and installed in a COM+ server application.

9.
Join the actions with the respective implementations, as shown in Figure 13.16.

Before looking at the Data page, look at the failure and compensation pages. Figure 13.17 shows the On Failure of BuyPole page.

Figure 13.17. The On Failure of BuyPole page in NestedTxn.skv.


On the page shown in Figure 13.17, we perform the actions needed to handle the transaction failure for BuyPole, which for this example is to send a message to stop building the tower and, more importantly, aborting the enclosing (long-lived) transaction Setup Cell Tower. Recall that the actions on this page are executed in lieu of the actions inside the BuyPole transaction. Hence, the Abort shape aborts the outer transaction.

Next, look at Compensation for BuyPole page, shown in Figure 13.18.

Figure 13.18. Compensation for BuyPole page in NestedTxn.skv.


The page shown in Figure 13.18 is executed when the outer transaction, Setup Cell Tower, fails, but the nested BuyPole transaction succeeded. Our compensatory action is to get rid of the bought pole as best as we can. The key point about compensation is that you cannot undo or abort something (such as a transaction) that has already happened in the real world; you can at best take corrective action.

Two other process pages are not shown: On Failure of Setup Cell Tower and On Failure of DigHole. These are similar to the ones being discussed here. When the outer transaction fails, we simply send a message to write up a status report for the failure of erecting a cell tower. When the DigHole transaction fails, we also cause the outer transaction to abort, just as we did in On Failure of BuyPole.

Now look at the Data page shown in Figure 13.19.

Figure 13.19. Data page for NestedTxn.Skv.


On the Data page, we add Constants strings to use with each of the messages. Six string constants are shown; however, one is not used. It would have been useful if we could have handled a compensation procedure for a hole already dug but one no longer necessary. The constants are as shown in Table 13.3.

Table 13.3. Strings in NestedTxn.Skv
NameValue
PayToFillHolePay to fill the hole already dug! (This constant is not used in the schedule.)
NoPoleNo pole. Stop setting up the tower!
SellPoleAuction off the bought pole!
WriteReportTower setup failed. Write project status report.
BuildTheTowerBuild the tower!
NoHoleNo hole. Stop setting up the tower!

Caution

Be careful with the messages that get the auto-numbered suffixes. The same suffixed message in your schedule may refer to a different port from the one shown in the figures. For example, ShowMsgBox_in_2 may apply to Port_3 in your schedule, whereas it applies to Port_1 in a schedule shown in this chapter.

To correctly reproduce the schedules, you must match the message and the port through which the message passes.


When you run this schedule, you will be successively presented with two dialog boxes. The first one asks whether you want to abort the transaction, which is BuyPole. The second one asks whether you want to abort the transaction, which is DigHole. You can try out the different combinations yourself; however, the interesting one is when you successfully buy a pole but fail to dig a hole for it. The DbMon trace for it is shown in Listing 13.11.

Listing 13.11. DbMon Trace for NestedTxn.skx
2544: 2:37:57 PM:AdvOrchTxn.CAbortTxn: Class_Initialize()
2544: 2:37:59 PM:AdvOrchTxn.CAbortTxn: AskToAbort(): SetComplete!
2544: 2:37:59 PM:AdvOrchTxn.CAbortTxn: Class_Terminate()
2544: 2:37:59 PM:AdvOrchTxn.CAbortTxn: Class_Initialize()
2544: 2:38:00 PM:AdvOrchTxn.CAbortTxn: AskToAbort(): Aborted!
2544: 2:38:00 PM:AdvOrchTxn.CAbortTxn: Class_Terminate()
2544: AdvOrchUtil.CMsg: Class_Initialize()
2544: AdvOrchUtil.CMsg: ShowMsgBox(): Msg=No hole, Stop setting up tower! Title=

2544: AdvOrchUtil.CMsg: Class_Terminate()
2544: AdvOrchUtil.CMsg: Class_Initialize()
2544: AdvOrchUtil.CMsg: ShowMsgBox(): Msg=Auction off the bought pole! Title=
2544: AdvOrchUtil.CMsg: Class_Terminate()
2544: AdvOrchUtil.CMsg: Class_Initialize()
2544: AdvOrchUtil.CMsg: ShowMsgBox(): Msg=Tower setup failed.  Write project status
 report! Title=
2544: AdvOrchUtil.CMsg: Class_Terminate()

Listing 13.11 shows that the first DTC style transaction to buy the pole is completed (trace SetComplete!), whereas the second one is aborted (trace Aborted!). When the second transaction is aborted, the On Failure of DigHole page is executed. This process sends a message declaring "No hole, stop setting up tower!", and it aborts the outer Setup Cell Tower transaction. When the outer transaction is aborted, the compensation process starts. The Compensation for BuyPole page is executed. The process on this page sends the message to "Auction off the bought pole!". After all the compensation processes have finished (there is only one in this example), the On Failure of Setup Cell Tower page for the outer transaction is executed. This sends the message to "Write project status report!".

You could develop this example further by making both BuyPole and DigHole long-running transactions containing multiple steps with transactions that proceed concurrently. Such a long-lived process could occur over months, and the XLANG schedule would track this process just fine.

Long-running transactions sacrifice isolation; therefore, actions within a long running transaction may be exposed to inconsistent data. In our contrived example, if you don't take care of this in your application logic, the setup instructions may not match the hole you dug or the pole you bought. However, your installers just may be used to such state of affairs. See Chapter 9 for more information on transactions.

The next section investigates transactions and state with the iteration shape.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset