Click here to Skip to main content
Click here to Skip to main content

Passing WCF transactions to COM+

, 28 Aug 2012 CPOL
Rate this:
Please Sign up or sign in to vote.
This article provides a program to demonstrate how to pass WCF transactions to COM+.

Introduction

A lot of business logic runs in COM+ classes. There is increasingly a need to expose this logic in WCF services. When WCF services are configured as web services, any client may access them. WCF services may run in transactions. When a WCF service calls a COM+ method, this method should run in the same transaction in which the WCF service runs. This program shows how to do this, as there is little documentation on this subject.

Background

COM+

COM+ functionality in .NET is available under the System.EnterpriseServices namespace. Any class that inherits the ServicedComponent class runs in COM+. If in addition the class has the attribute Transaction(TransactionOption.Required) defined, the methods of this class run in a transaction.

WCF

WCF functionality in .NET is available under the System.ServiceModel namespace. A WCF service is implemented by the ServiceHost class. This class takes as argument in the constructor the class that implements the methods of the service. The methods that have the attribute OperationBehavior(TransactionScopeRequired:=True) run in a transaction.

Calling COM+ from WCF

A WCF service may instantiate a COM+ class and call a method of that class. However, the COM+ method will run in a new transaction. In order for the COM+ method to run in the same transaction, the transaction scope's InteropOption must be set to Full:

Using s As New TransactionScope(Transaction.Current, _
           New TimeSpan(0, 1, 0), EnterpriseServicesInteropOption.Full)
    'Call COM+
End Using

Using the code

This program is a modified version of the Service Transaction Behavior sample of Microsoft's MSDN/Windows Communication Foundation Samples/Basic/Services/Transaction. The difference is that the data access layer resides in the additional COM+ class, rather in the service. The solution contains four projects:

  1. Tests.BE: contains the business entities, in this case only the typed dataset LogData. The post build events register the assembly in GAC.
  2. Tests.DA: data-access layer that provides methods to retrieve and update records in a database. The post build events register the assembly in GAC and COM+ and copy the config file to the respective GAC folder. The connection string is defined in the app.config file. The assembly contains the following classes:
    1. ClassBase: class running in COM+, providing functions to read data from the database and execute SQL statements.
    2. ClassU: class running in COM+, uses or creates a transaction and provides a function to update a table with the changes recorded in a dataset.
  3. Tests.WS: implements the WCF service, and contains the following classes:
    1. ICalculator: interface defining service methods. Example:
    2. <OperationContract()><TransactionFlow(TransactionFlowOption.Mandatory)>Function Add(ByVal n As Double) As Double
    3. CalculatorService: implementation of the service methods. Each method does a calculator operation, and writes a record to the Log table of the database. Example:
    4. <OperationBehavior(TransactionScopeRequired:=True, TransactionAutoComplete:=True)> _
      Public Function Add(ByVal n As Double) As Double Implements ICalculator.Add
          Using s As New TransactionScope(Transaction.Current, New TimeSpan(0, 1, 0), EnterpriseServicesInteropOption.Full)
              RecordToLog([String].Format(CultureInfo.CurrentCulture, "Adding {0} to {1}", n, runningTotal))
              runningTotal = runningTotal + n
              s.Complete()
          End Using
          Return runningTotal
      End Function
    5. Program: contains the code to start the service:
    6. host = New ServiceHost(GetType(CalculatorService))
  4. Tests.UI: Contains a Windows form to test the services. The form provides the button Test WS, which initiates a WCF transaction, calls sequentially the four methods of the service, and if successful, marks the transaction as completed.
  5. Dim client As New Tests.PX.CalculatorClient()
    Using tx As New TransactionScope()
        client.Add(100)
        ...
        tx.Complete()
    End Using
    client.Close()

To run the program, follow these steps:

  1. With Visual Studio 2010 open solution Tests.WCFTrans.sln.
  2. Set the connection string in app.config. It must be a valid connection string to a database, on which you have the right to create tables.
  3. Build the solution. If it fails, check that the paths to gacutil and regsvcs in the post-build events are correct.
  4. You may look in Component Services (Start/Run/comexp.msc) that the COM+ application Tests.DA has been created.
  5. Start the WCF service by double-clicking on Tests.WS\bin\Tests.WS.exe. This will open a command window like the following:
  6. Service command window

  7. Start Tests.UI either in the debugger, or with the executable Tests.UI\Debug\bin\Tests.UI.exe. The following form appears:
  8. Test form

  9. Choose the menu item File/Recreate tables. This will create the tables Log and Log_Audit on the database.
  10. Press the button Test WS. This will initiate a transaction, call the four methods of the service, and complete the transaction. If successful, the following will be displayed:
  11. Test form after successfull run.

  12. To check that the data was written to the database, issue the command: SELECT * FROM Log on the database.
  13. Stop the service by pressing Enter in the command window mentioned before.
  14. To check that no data is saved when an error occurs in the service, add the following code in the Divide method of the class CalculatorService before the statement s.Complete():
  15. Throw New Exception("Ex1")
  16. Recompile Tests.WS, and start it as before.
  17. In the form of Tests.UI click the button Test WS again. An error message will appear.
  18. Check that no data was written to the database as before with the same SQL command. The reason is that although the service methods Add, Delete, and Multiply are completed successfully and wrote to the database, the service method Divide fails. The transaction is aborted and the changes in the database are rolled back.
  19. You may throw an exception in COM+, as well as in the UI, and the data is rolled back.

History

  1. WCF service CalculatorService uses COM+. UI initiates transaction and calls the service.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Alexandros Pappas
Software Developer (Senior)
Greece Greece
No Biography provided

Comments and Discussions

 
GeneralMy vote of 5 PinmvpKanasz Robert19-Sep-12 4:52 
QuestionThank you PinmemberSarafian28-Aug-12 20:56 
GeneralMy vote of 4 PinmemberChristian Amado28-Aug-12 12:48 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web03 | 2.8.141022.2 | Last Updated 28 Aug 2012
Article Copyright 2012 by Alexandros Pappas
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid