Building Transactional Components

Archived content. No warranty is made as to technical accuracy. Content may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist.

This section introduces transactional components and the benefits of running components within the same transaction.

 

viicsc

Scenario: Composing Work from Multiple Components Under the Same Transaction
Add new functionality to transfer money between accounts by adding a new component, MoveMoney, which uses the existing Account component.

 

viic01

Creating the MoveMoney Component
Use the CreateInstance method to run the MoveMoney and Account components within the same transaction.

 

viic02

Monitoring Transactions
Use the Bank client to run your components, and use the Microsoft Transaction Server Explorer to monitor transactions.

 

viicno

Application Design Notes: Using Context and Transactions
Using transactional components provides atomicity and simplified error recovery.

Scenario: Composing Work from Multiple Components Under the Same Transaction

For this scenario, you will add new functionality that allows you to transfer money between two accounts. To implement this, you add a new component, MoveMoney. MoveMoney creates Account and then calls it once for a credit or debit, or twice for a transfer, as shown here.

Cc723274.vi0701(en-us,TechNet.10).gif

Because either MoveMoney or Account could fail at any point, all database updates need to be in the same transaction to ensure that the database remains consistent. To do this, you configure the MoveMoney and Account components in the Microsoft Transaction Server Explorer to require a transaction. Transaction Server ensures that all their objects' work is automatically done in the same transaction.

Cc723274.vi0702(en-us,TechNet.10).gif

Creating the MoveMoney Component

To implement this scenario, you will add a new class module, MoveMoney, to the Account project. MoveMoney has a single method, Perform, which creates an Account object to perform the credit, debit, or transfer.

To create the MoveMoney component

  1. Open the \Mts\Samples\Account.VB\Step4\Account.vbp project.

  2. Build the component as a dynamic-link library (DLL) and save it as \Mts\Samples\Account.VB\Step4\VBAcct.dll.

By adding a new class module, you have added a new COM component to this DLL. Therefore, you will need to delete the Account component in the Microsoft Transaction Server Explorer and then install the Account and the MoveMoney components.

To reinstall your components

  1. Remove the Account and CreateTable components.

  2. Add the new components.

    Use the DLL you created in the previous procedure. You can find it in \Mts\Samples\Account.VB\Step4\VBAcct.dll.

MTS enlists a component in a transaction as specified by the component's transaction attribute. For this scenario, Account and MoveMoney run within the same transaction.

To set the transaction attributes for your components

  1. For the Account and MoveMoney components, set the transaction attribute to Requires a transaction.

  2. For the CreateTable component, set the transaction attribute to Requires a new transaction.

The MoveMoney object uses CreateInstance to create the Account object. CreateInstance is a method on the context object. By using CreateInstance, the Account object created by MoveMoney shares context with MoveMoney.

Dim objAccount As Bank.Account
Set objAccount = _
    GetObjectContext.CreateInstance("Bank.Account")

Transactions are associated with an object's context. Because both MoveMoney and Account have a transaction attribute of Requires a transaction, the Account object will be enlisted within the same transaction as MoveMoney.

In Building Scalable Components, you learned how to use SetComplete to indicate that an object has finished its work and can be deactivated. For transactional components, calling SetComplete indicates that a transaction can be committed.

GetObjectContext.SetComplete

When the Perform method returns, the transaction attempts to commit. There is no guarantee that it will commit, however. If an error occurs, Perform instead calls SetAbort.

GetObjectContext.SetAbort

SetAbort also indicates that an object has finished its work, but that it isn't in a consistent state. When the Perform method returns after calling SetAbort, the attempt to commit the transaction won't succeed.

Monitoring Transaction Statistics

You can use the Microsoft Transaction Server Explorer to monitor commit and abort statistics for transactions.

You can experiment with the MoveMoney and Account components to see how transactions are committed and aborted as you provide user input with the Bank client.

To monitor transactions

  1. On the Window menu of the Transaction Server Explorer, click New Window.

  2. In the left pane, click Transaction Statistics.

  3. On the Action menu, click Scope Pane to hide the left pane of the Explorer.

  4. Make sure that the Microsoft Distributed Transaction Coordinator (MS DTC) is running on your SQL Server computer. You can start MS DTC from the Transaction Server Explorer or from SQL Server.

  5. Also make sure that you have the ODBC data source set up, and that SQL Server is running.

  6. Start the Bank client.

    Rearrange the windows so that you see the two Microsoft Transaction Server Explorer windows and the Bank client window.

To monitor a commit, click Submit in the Bank client. The Transaction Statistics window first indicates that one transaction is active, and indicates that one transaction was committed.

To monitor an abort, click Debit in the Bank client, and enter an amount for the transaction that is greater than the balance on your account. Click Submit. The Transaction Statistics window first indicates that one transaction is active, and then indicates that one transaction was aborted.

Try experimenting with Transfer. Verify that both objects are running within the same transaction by checking the balance of two accounts and performing a transfer that would overdraw from an account. Notice that both the credit and the debit are aborted.

Application Design Notes: Using Context and Transactions

Context simplifies defining transactions. A transaction is automatically started when a component is declared as transactional. Components don't need to add additional code to indicate the start and end of a transaction. Using context allows you to define the scope of a transaction.

Besides simplifying building components, automatic transaction enlistment also allows for reuse of existing components. Changing the transaction attribute is the only change to the Account component from the previous section, Building Scalable Components.

Creating the Account object from MoveMoney establishes MoveMoney as the root of the transaction. The root transaction attempts to commit after it has completed its work. If an Account object calls SetAbort to indicate that it cannot successfully commit its work, then when the root transaction attempts to commit, the entire transaction will fail.

In the case of a money transfer, this provides atomicity. If a credit succeeds, but insufficient funds prevent the debit from succeeding, then the credit will be rolled back from the database automatically. Thus, SetAbort provides simplified error recovery.

Context simplifies the development of the component. Each object independently acquires its own resources, performs its work, and indicates its own internal state by using SetComplete or SetAbort before returning.