You want to perform multiple operations with different data sources, and you want these operations to either fail or succeed as a unit.
Derive your class from
ServicedComponent
, specify the type of transactional behavior you want by adding the
Transaction
attribute to the class declaration, and add the
AutoComplete
attribute to all
COM+ allows you to create classes that have set transaction requirements. When a client uses a method in a transactional class, a transaction will be started automatically, and committed when the code completes. Coding transactions in this way is easy and transparent. It also allows you to flexibly tie multiple methods together in a single transaction at runtime. However, COM+ transactions require the Distributed Transaction Coordinator (DTC) service on the computer to coordinate all transactions using a two-stage commit process. This is
To use distributed transactions, you must first create a serviced component, as described in recipe 17.11. Then, add the System.EnterpriseServices.Transaction attribute to the class that will run inside the transaction and specify a value from the TransactionOption enumeration. Supported values include
Required This object must run in a transaction. If the caller has already started a transaction, this object participates inside that transaction. Otherwise, a new transaction is created.
RequiresNew This object must run in a transaction. If the caller has already started a transaction, a new and completely independent transaction is created for this object.
Supported This object can run in a transaction and is enlisted in the caller's transaction if it exists. Otherwise, this object doesn't run in a transaction.
NotSupported This object doesn't participate in a transaction. If the caller has a current transaction, this object can't vote on it.
Disabled The object doesn't have any transaction requirements. This is the default value. In .NET, this value is equivalent to NotSupported .
In a COM+ transaction, every participating object must vote to commit or abort the transaction. If any object
The following class provides an AttemptChanges method that modifies a SQL Server database. However, before the method completes, an unhandled exception is thrown, and the entire transaction is rolled back.
<Transaction(TransactionOption.Required)> _ Public Class TransactionTest Inherits ServicedComponent Private ConnectionString As String = "Data Source=localhost;" & _ "Integrated Security=SSPI;Initial Catalog=Northwind" <AutoComplete()> _ Public Sub AttemptChanges() ' Delete records from SQL Server. Dim Con As New SqlConnection(ConnectionString) Dim Cmd As New SqlCommand("DELETE * FROM Customers", Con) Try Con.Open() Cmd.ExecuteNonQuery() Finally Con.Close() End Try ' (Access another data source here.) ' This unhandled exception will cause all transactional ' operations to be rolled back. ' You could also set the vote manually using ' ContextUtil.MyTransactionVote = TransactionVote.Abort ' ContextUtil.DeactivateOnReturn = True Throw New ApplicationException("Task aborted.") End Sub End Class
| Note |
If a data source supports COM+ transactions, it will automatically be enlisted in the current transaction. However, some operations (such as writing a file to disk) are inherently not transactional. That means that these operations won't be rolled back if the transaction fails. |