使用单阶段提交和可提升的单阶段通知进行优化

本主题描述由 System.Transactions 基础结构提供的优化性能的机制。

可提升的单阶段登记

基础结构 System.Transactions 管理单个应用程序域中的事务,该事务最多涉及单个持久资源或多个易失性资源。 System.Transactions由于基础结构仅使用应用程序内域调用,因此会产生最佳的吞吐量和性能。

但是,如果将事务提供给同一台计算机上另一个应用程序域中的另一个对象(包括跨进程和计算机边界),或者如果要登记另一个持久资源管理器,System.Transactions 基础结构会自动升级事务,以便由 MSDTC 管理。 由 MSDTC 管理的事务不像由 System.Transactions 基础结构管理事务那样有利于性能的提高。

为了优化性能,System.Transactions 基础结构提供了可提升的单阶段登记(PSPE),允许位于不同应用程序域、进程或计算机上的单个远程持久资源参与 System.Transactions 事务,而不会导致该事务升级为 MSDTC 事务。 如果需要,此资源管理器(RM)可以托管并“拥有”事务,该事务稍后可以升级到分布式事务(或 MSDTC 事务)。 这可以减少使用 MSDTC 的机会。

此特定资源管理器通常有自己的内部非分布式事务,它需要支持在运行时将这些事务转换为分布式事务。 例如,SQL Server 2005 是这样的资源管理器。 在这种情况下,System.Transactions 基础结构只需监视事务是否需要升级就可发挥积极的管理作用。 为了支持基础结构与资源管理器之间的 System.Transactions 交互,后者需要实现接口 IPromotableSinglePhaseNotification

该方法 EnlistPromotableSinglePhase 用于登记可稍后升级的单个持久资源。 此方法可确保根据需要升级登记。 如果该登记成功,则 RM 会创建其内部事务,并将该事务与 System.Transactions 事务关联。 如果 PSPE 登记失败,则 RM 应改用 EnlistDurable 方法进行登记。 PSPE 登记失败可能会发生,当事务已是分布式事务,或者另一个资源管理器 (RM) 已执行 PSPE 登记时。

登记后,分别通过调用 System.TransactionsSinglePhaseCommit 方法,将客户端用于提交或中止 Rollback 事务的调用转换为对资源管理器的调用。

如果 System.Transactions 事务从不需要升级,则在事务提交时,RM 将会收到 SinglePhaseCommit 通知。 这样,就可以提交最初创建的内部事务。

如果需要升级 System.Transactions 事务(例如,要支持多个 RM),则 System.Transactions 会通过在 Promote 接口(从其派生 ITransactionPromoter 接口)上调用 IPromotableSinglePhaseNotification 方法,向资源管理器发出通知。 然后,资源管理器将事务从本地事务(不需要日志记录)内部转换为能够参与 DTC 事务的事务对象,并将其与已完成的工作相关联。 当事务被要求提交时,事务管理器仍会向 SinglePhaseCommit 资源管理器发送通知,该通知会提交在升级期间创建的分布式事务。

注释

TransactionCommitted 跟踪(在对已升级的事务调用 Commit 时生成)包含 DTC 事务的活动 ID。

有关管理升级的详细信息,请参阅 事务管理升级

事务管理升级场景

下面的方案演示如何将一个事务升级为分布式事务,该方案将 System.Data 命名空间用作资源管理器的“代理”。 该方案假定该事务中已包含一个至数据库的 System.Data 连接 CN1,并且应用程序希望包含另一个 System.Data 连接 CN2。 该事务必须作为完全分布式的两阶段提交事务升级到 DTC。

在此情境中,

  1. CN1 调用 EnlistPromotableSinglePhase 方法以在该事务中登记。 这样,该事务仍是本地事务,并且该事务上没有其他可提升的登记,因此 EnlistPromotableSinglePhase 调用会成功执行。

  2. 当第二个连接 CN2 调用 EnlistPromotableSinglePhase 时,该调用会因包含另一个可提升的登记而失败。 因此,CN2 必须获取 DTC 事务才能将它传递给 SQL。 为此,它使用TransactionInterop类提供的方法之一来生成可供 SQL 使用的事务格式。

  3. System.Transactions 在 CN1 实现的 Promote 接口上调用 ITransactionPromoter 方法。

  4. 此时,CN1 使用 SQL 2005 和 System.Data 特定的某一机制升级该事务。

  5. 该方法的 Promote 返回值是一个字节数组,其中包含事务的传播令牌。 System.Transactions 使用此传播标记创建可以合并到本地事务的 DTC 事务。

  6. 此时,CN2 可以使用通过调用其中一种方法 TransactionInterop 接收的数据将事务传递给 SQL。

  7. 现在,这两个连接都登记到了 DTC 分布式事务中。

单阶段提交优化

在运行时,单阶段提交协议更高效,因为所有更新都是在没有任何显式协调的情况下完成的。 若要利用此优化,应使用ISinglePhaseNotification接口实现资源管理器,并使用EnlistDurableEnlistVolatile方法在事务中登记。 具体而言,EnlistmentOptions 参数应等于 None,以确保执行单个阶段提交。

ISinglePhaseNotification由于该接口派生自IEnlistmentNotification接口,如果 RM 不符合单阶段提交的条件,它仍然可以接收两个阶段提交通知。 如果 RM 从 TM 接收到 SinglePhaseCommit 通知,它应尝试完成提交所需的工作,并在 Committed 参数上调用 AbortedInDoubtSinglePhaseEnlistment 方法,来相应地通知事务管理器是提交还是回滚事务。 在此阶段中,登记时的 Done 响应表示 ReadOnly 语义。 因此,不应答复 Done 以及任何其他方法。

如果只有一个可变登记且没有持久登记,则易失登记将收到 SPC 通知。 如果有任何可变登记并且只有一个持久登记,则可变登记会接收 2PC。 完成提交后,持久登记会接收到 SPC 通知。

另请参阅