65.9K
CodeProject 正在变化。 阅读更多。
Home

将 WCF 事务传递给 COM+

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.89/5 (2投票s)

2012年8月28日

CPOL

4分钟阅读

viewsIcon

20303

downloadIcon

188

本文提供了一个程序,演示了如何将 WCF 事务传递到 COM+。

引言

许多业务逻辑运行在 COM+ 类中。将这些逻辑公开为 WCF 服务日益成为一种需求。当 WCF 服务配置为 Web 服务时,任何客户端都可以访问它们。WCF 服务可以运行在事务中。当 WCF 服务调用 COM+ 方法时,该方法应该在 WCF 服务运行的同一事务中运行。本程序展示了如何实现这一点,因为关于此主题的文档很少。

背景

COM+

NET 中的 COM+ 功能可在 System.EnterpriseServices 命名空间下使用。任何继承 ServicedComponent 类的类都在 COM+ 中运行。如果此外,该类还定义了 Transaction(TransactionOption.Required) 属性,则该类的所有方法都将在事务中运行。

WCF

NET 中的 WCF 功能可在 System.ServiceModel 命名空间下使用。WCF 服务由 ServiceHost 类实现。该类在构造函数中接收实现服务方法的类作为参数。具有 OperationBehavior(TransactionScopeRequired:=True) 属性的方法将在事务中运行。

从 WCF 调用 COM+

WCF 服务可以实例化一个 COM+ 类并调用该类的一个方法。但是,COM+ 方法将在新事务中运行。为了使 COM+ 方法在同一事务中运行,事务范围的 InteropOption 必须设置为 Full

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

Using the Code

此程序是 Microsoft MSDN/Windows Communication Foundation Samples/Basic/Services/Transaction 的 Service Transaction Behavior 示例的一个修改版本。区别在于数据访问层驻留在额外的 COM+ 类中,而不是服务中。该解决方案包含四个项目

Dim client As New Tests.PX.CalculatorClient()
Using tx As New TransactionScope()
    client.Add(100)
    ...
    tx.Complete()
End Using
client.Close()
  1. Tests.BE:包含业务实体,在本例中仅包含类型化数据集 LogData。生成后事件会将程序集注册到 GAC。
  2. Tests.DA:数据访问层,提供从数据库检索和更新记录的方法。生成后事件会将程序集注册到 GAC 和 COM+,并将config文件复制到相应的 GAC 文件夹。连接字符串定义在app.config文件中。程序集包含以下类
    1. ClassBase:在 COM+ 中运行的类,提供从数据库读取数据和执行 SQL 语句的功能。
    2. ClassU:在 COM+ 中运行的类,使用或创建事务,并提供一个函数,用 dataset 中记录的更改更新表。
  3. Tests.WS:实现了 WCF 服务,并包含以下类
    <OperationContract()><TransactionFlow_
    (TransactionFlowOption.Mandatory)>Function Add(ByVal n As Double) As Double
    <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
    host = New ServiceHost(GetType(CalculatorService))
    1. ICalculator:定义服务方法的接口。示例
    2. CalculatorService:服务方法的实现。每个方法执行一个计算器操作,并将一条记录写入数据库的 Log 表。示例
    3. Program:包含启动服务的代码
  4. Tests.UI:包含一个用于测试服务的 Windows 窗体。该窗体提供“Test WS”按钮,该按钮会启动一个 WCF 事务,按顺序调用服务的四个方法,如果成功,则将事务标记为已完成。

要运行程序,请执行以下步骤

Throw New Exception("Ex1")
  1. 使用 Visual Studio 2010,打开解决方案Tests.WCFTrans.sln
  2. app.config中设置连接字符串。它必须是有效连接字符串,指向您有权创建表的数据库。
  3. 生成解决方案。如果失败,请检查生成后事件中 gacutil 和 regsvcs 的路径是否正确。
  4. 您可以在组件服务 (Start/Run/comexp.msc) 中查看 COM+ 应用程序 Tests.DA 是否已创建。
  5. 通过双击Tests.WS\bin\Tests.WS.exe启动 WCF 服务。这将打开一个命令窗口,如下所示

    Service command window

  6. 在调试器中或使用可执行文件Tests.UI\Debug\bin\Tests.UI.exe启动 Tests.UI。将出现以下窗体

    Test form

  7. 选择菜单项**文件/重新创建**表。这将会在数据库上创建 LogLog_Audit 表。
  8. 按“Test WS”按钮。这将启动一个事务,调用服务的四个方法,然后完成事务。如果成功,将显示以下内容

    Test form after successful run.

  9. 要检查数据是否已写入数据库,请在数据库上执行命令:SELECT * FROM Log
  10. 通过按前面提到的命令窗口中的**Enter**键停止服务。
  11. 要检查在服务中发生错误时是否未保存任何数据,请在 CalculatorService 类的 Divide 方法中,在 s.Complete() 语句之前添加以下代码
  12. 重新编译 Tests.WS,并按原样启动它。
  13. Tests.UI 的窗体中,再次单击“Test WS”按钮。将出现一条错误消息。
  14. 使用与以前相同的 SQL 命令检查数据库中是否没有写入任何数据。原因是,尽管服务方法 AddDeleteMultiply 已成功完成并写入数据库,但服务方法 Divide 失败。事务被中止,数据库中的更改被回滚。
  15. 您可以在 COM+ 和 UI 中引发异常,数据也会被回滚。

历史

  1. WCF 服务 CalculatorService 使用 COM+。UI 启动事务并调用服务。
© . All rights reserved.