ADO.NET事务有很多值得学习的地方,这里我们主要介绍在事务中将资源登记为参与者,包括介绍持久登记等方面。参与事务的每个资源都由资源管理器进行管理,而后者的操作则由事务管理器进行协调。这一协调通过通知来执行,这些通知会提供给已通过事务管理器在事务中登记的订户。本主题介绍如何在事务中登记一个资源(或多个资源)以及不同的登记类型。在单阶段和多阶段中提交事务主题介绍如何在已登记的资源之间协调事务提交。
在ADO.NET事务中登记资源
资源若要参与事务,它必须在事务中进行登记。Transaction类定义了一组提供此功能的方法,这些方法的名称以Enlist开头。不同的Enlist方法对应于资源管理器可能具有的不同登记类型。具体来说,EnlistVolatile方法用于登记可变资源,而EnlistDurable方法则用于登记持久资源。
#T#资源管理器的持久性(反之为可变性)是指资源管理器是否支持故障恢复。如果资源管理器支持故障恢复,则它会在第1阶段(准备阶段)将数据保存到持久存储区中;这样,一旦资源管理器出现故障,它就可在恢复时在事务中重新登记,并根据从TM接收到的通知执行适当的操作。通常,可变资源管理器管理如内存中的数据结构之类的可变资源(如内存中的事务处理哈希表),而持久资源管理器则管理具有更持久的后备存储区的资源(例如,其后备存储区为磁盘的数据库)。
为了简单起见,在根据资源的持久性支持决定是使用EnlistDurable还是EnlistVolatile方法后,应为资源管理器实现IEnlistmentNotification接口,从而将资源登记为参与两阶段提交(2PC)。有关2PC的更多信息,请参见在单阶段和多阶段中提交事务。单个参与者可以多次调用EnlistDurable和EnlistVolatile来登记到其中的某一协议。
持久登记
EnlistDurable方法用于登记要作为持久资源参与事务的资源管理器。如果持久资源管理器在ADO.NET事务执行期间关闭,则它在重新联机后,应在它作为参与者且未完成第2阶段的所有事务中重新登记(使用Reenlist方法)来执行恢复,并在完成恢复处理后调用RecoveryComplete。有关恢复的更多信息,请参见执行恢复。
EnlistDurable方法都采用Guid对象作为其第一个参数。事务管理器使用Guid将持久登记与特定的资源管理器关联。因此,资源管理器在重新启动后必须统一使用同一Guid来标识自身,即使跨不同的资源管理器时也是如此;否则恢复操作就可能失败。
EnlistDurable方法的第二个参数是对资源管理器所实现的用于接收事务通知的对象的引用。您所使用的重载会向事务管理器通知资源管理器是否支持单阶段提交(SPC)优化。大多数情况下,应实现IEnlistmentNotification接口来参与两阶段提交(2PC)。但如果要优化提交过程,可考虑实现ISinglePhaseNotification接口来参与SPC。有关SPC的更多信息,请参见在单阶段和多阶段中提交事务和使用单阶段提交和可提升的单阶段通知进行优化。
第三个参数是EnlistmentOptions枚举,该枚举的值可以为None或EnlistDuringPrepareRequired。如果将该值设置为EnlistDuringPrepareRequired,则这种登记类型可在从事务管理器接收到准备通知时登记附加资源管理器。但是,您应清楚这种登记类型不适合执行单阶段提交优化。
可变登记
管理可变资源(如缓存)的参与者应使用EnlistVolatile方法进行登记。此类对象可能无法获取事务的结果,或者在系统出现故障后可能无法恢复它们所参与的任何事务的状态。
如前面所述,资源管理器在管理内存中的可变资源时应进行可变登记。使用EnlistVolatile的优点之一就是不会强制执行不必要的事务升级。有关事务升级的更多信息,请参见事务管理升级主题。登记可变性意味着事务管理器处理登记的方式与事务管理器对资源管理器的预期行为之间存在差异。这是因为可变资源管理器不执行恢复。EnlistVolatile方法不采用Guid参数,因为可变资源管理器不执行恢复,并且不会调用需要Guid的Reenlist方法。
与持久登记一样,无论使用哪种重载方法进行登记,都会向事务管理器指示资源管理器是否支持单阶段提交优化。由于可变资源管理器不能执行恢复,因此在准备阶段不会为可变登记写入任何恢复信息。因此,调用RecoveryInformation方法会导致InvalidOperationException。