about_Transactions

应用到: Windows PowerShell 2.0, Windows PowerShell 3.0, Windows PowerShell 4.0, Windows PowerShell 5.0

主题

about_Transactions

简短说明

介绍如何在 Windows PowerShell® 中管理事务处理操作。

详细说明

从 Windows PowerShell 2.0 开始,Windows PowerShell 中支持事务。该功能让你可以启动一个事务,指示哪些命令是事务的一部分以及提交或回滚事务。

关于事务

在 Windows PowerShell 中,事务是一组(一个或多个)作为逻辑单元被管理的命令。事务的状态可以是已完成(“已提交”),这将更改受事务影响的数据。或者,事务的状态可以是完全撤消(“已回滚”),以便受影响的数据不会被事务更改。

由于事务中的命令是作为一个单元进行管理,因此所有命令不是全部提交就是全部回滚。

事务在数据处理中使用广泛,尤其是在数据库操作以及财务交易记录领域最为常见。最常使用事务的情况是:当对于一组命令而言,最差的情况并非这些命令全部失败,而是其中有些成功了,而其余的失败了,进而使得系统处于难以修复的受损、故障或无法解释的状态。

TRANSACTION CMDLET

Windows PowerShell 包括专为管理事务而设计的多个 cmdlet。

      Cmdlet                 Description
      --------------         ---------------------------------    
      Start-Transaction      Starts a new transaction. 

      Use-Transaction        Adds a command or expression to the
                             transaction. The command must use
                             transaction-enabled objects.

      Undo-Transaction       Rolls back the transaction so that
                             no data is changed by the transaction.

      Complete-Transaction   Commits the transaction. The data
                             affected by the transaction is changed.

      Get-Transaction        Gets information about the active
                             transaction.

有关 transaction cmdlet 的列表,请键入:

          get-command *transaction

有关 cmdlet 的详细信息,请键入:

          get-help <cmdlet-name> -detailed

例如:

          get-help use-transaction -detailed

启动了事务的元素

若要参与一个事务,cmdlet 和提供程序必须都支持事务。此功能内置到受事务影响的对象中。

在 Windows Vista 中,Windows PowerShell Registry 提供程序支持事务。TransactedString 对象 (Microsoft.PowerShell.Commands.Management.TransactedString) 处理任何运行 Windows PowerShell 的操作系统。

其他 Windows PowerShell 提供程序可以支持事务。若要在你的会话中查找支持事务的 Windows PowerShell 提供程序,请使用以下命令在提供程序的 Capabilities 属性中查找“Transactions”值:

        get-psprovider | where {$_.Capabilities -like "*transactions*"}

有关提供程序的详细信息,请参阅“帮助”了解有关提供程序的信息。若要获取提供程序“帮助”,请键入:

        get-help <provider-name>

例如,若要获取 Registry 提供程序的“帮助”,请键入:

        get-help registry

UseTransaction 参数

可支持事务的 cmdlet 具有 UseTransaction 参数。此参数包括活动事务中的命令。你可以使用完整参数名或其别名 "usetx"。

参数仅可在会话包含活动事务时使用。如果在没有活动事务的情况下,输入一个具有 UseTransaction 参数的命令,该命令将失败。

若要查找具有 UseTransaction 参数的 cmdlet,请键入:

        get-help * -parameter UseTransaction

在 Windows PowerShell 核心中,所有为处理 Windows PowerShell 提供程序而设计的 cmdlet 均支持事务。由此,你可以使用提供程序 cmdlet 来管理事务。

有关 Windows PowerShell 提供程序的详细信息,请参阅 about_Providers。

事务对象

事务在 Windows PowerShell 中通过事务对象 System.Management.Automation.Transaction 表示。

该对象具有以下属性:

RollbackPreference:

包含为当前事务设置的回滚首选项。当你使用 Start-Transaction 启动事务时,可以设置回滚首选项。

回滚首选项决定事务自动回滚的条件。有效值为 Error、TerminatingError 以及 Never。默认值为 Error。

Status:

包含事务的当前状态。有效值为 Active、Committed 以及 RolledBack。

SubscriberCount:

包含事务的订阅者数量。当你在一个事务正在执行的过程中启动了另一个事务时,订阅者将添加到事务中。当订阅者提交事务时,订阅者计数将递减。

活动事务

在 Windows PowerShell 中,一次仅有一个事务是活动的,并且你只能管理此活动事务。多个事务可在同一会话中同时进行,但只有最近启动的事务是活动的。

因此,当使用事务 cmdlet 时,无法指定特定事务。命令始终适用于活动事务。

这在 Get-Transaction cmdlet 的行为中最为明显。当你输入 Get-Transaction 命令时,Get-Transaction 始终只获取一个事务对象。此对象是表示活动事务的对象。

若要管理不同的事务,则必须先完成活动事务(通过将其提交或回滚)。当你执行此操作时,之前的事务将自动变为活动状态。事务将按其启动的相反顺序变为活动,从而最近启动的事务将始终是活动的。

订阅者与独立事务

如果你在另一事务正在执行时启动一个事务,默认情况下,Windows PowerShell 不会启动一个新的事务。反之,它会向当前事务添加一个“订阅者”。

当事务具有多个订阅者时,任何点上的单个 Undo-Transaction 命令为所有订阅者回滚整个事务。然而,若要提交事务,则必须为每个订阅者输入一个 Complete-Transaction 命令。

若要查找一个事务的订阅者数量,请检查事务对象的 SubscriberCount 属性。例如,以下命令使用 Get-Transaction cmdlet 来获取活动事务的 SubscriberCount 属性的值:

          (Get-Transaction).SubscriberCount

添加一个订阅者是默认行为,因为大多数在另一事务正在执行时启动的事务都与原始事务有关。在典型模型中,包含事务的脚本将调用包含其自己事务的帮助程序脚本。因为事务都是相关的,因此应回滚事务或将其作为一个单元提交。在此处插入部分正文。

然而,你可以通过使用 Start-Transaction cmdlet 的 Independent 参数,启动一个独立于当前事务的事务。

当你启动一个独立事务时,Start-Transaction 会创建一个新的事务对象,且该新的事务将变为活动事务。独立事务可以被提交或回滚,而不影响原始事务。

当完成独立事务(已提交或已回滚)后,原始事务将再次变为活动事务。

更改数据

当你使用事务更改数据时,受事务影响的数据将不会被更改,直至提交了事务。然而,相同的数据可由并非为事务一部分的命令更改。

当你正在使用事务管理共享数据时,请记住这一点。通常情况下,数据库具有这样的机制,即当你正在处理数据时将数据锁定,以阻止其他用户、其他命令、脚本、函数更改数据。

然而,锁定是数据库的一个功能。与事务不相关。如果你正在支持事务的文件系统或其他数据存储中工作,可以在事务正在执行时更改数据。

示例

本部分中的示例使用 Windows PowerShell Registry 提供程序,并假定你熟悉该程序。有关 Registry 提供程序的信息,请键入 "get-help registry"。

示例 1:提交事务

如要创建一个事务,请使用 Start-Transaction cmdlet。以下命令启动具有默认设置的事务。

        start-transaction

若要将命令包括在事务中,请使用 cmdlet 的 UseTransaction 参数。默认情况下,命令不包括在事务中,

例如,以下在 HKCU 的 Software 项中设置当前位置的命令:驱动器不包括在事务中。

        cd hkcu:\Software

以下创建 MyCompany 项的命令,使用 New-Item cmdlet 的 UseTransaction 参数将命令包括在活动事务中。

        new-item MyCompany -UseTransaction

命令返回表示新项的对象,但由于命令是事务的一部分,故注册表尚未更改。

        Hive: HKEY_CURRENT_USER\Software

        SKC  VC Name                           Property
        ---  -- ----                           --------
          0   0 MyCompany                      {}

若要提交事务,请使用 Complete-Transaction cmdlet。因为它始终影响活动事务,所以你无法指定该事务。

        complete-transaction

因此,MyCompany 项被添加到注册表。

        dir m*
       
        Hive: HKEY_CURRENT_USER\software

        SKC  VC Name                           Property
        ---  -- ----                           --------
         83   1 Microsoft                      {(default)}
          0   0 MyCompany                      {}

示例 2:回滚事务

如要创建一个事务,请使用 Start-Transaction cmdlet。以下命令启动具有默认设置的事务。

        start-transaction

以下创建 MyOtherCompany 项的命令,使用 New-Item cmdlet 的 UseTransaction 参数将命令包括在活动事务中。

        new-item MyOtherCompany -UseTransaction

命令返回表示新项的对象,但由于命令是事务的一部分,故注册表尚未更改。

        Hive: HKEY_CURRENT_USER\Software

        SKC  VC Name                           Property
        ---  -- ----                           --------
          0   0 MyOtherCompany                 {}

若要回滚事务,请使用 Undo-Transaction cmdlet。因为它始终影响活动事务,所以你无法指定该事务。

        Undo-transaction

其结果是,MyOtherCompany 项未添加到注册表中。

        dir m*
       
        Hive: HKEY_CURRENT_USER\software

        SKC  VC Name                           Property
        ---  -- ----                           --------
         83   1 Microsoft                      {(default)}
          0   0 MyCompany                      {}

示例 3:预览事务

通常情况下,事务中使用的命令会更改数据。然而,获取数据的命令在事务中也十分有用,因为它们在事务内部获取数据。这会提供提交事务将导致的更改的预览。

以下示例显示如何使用 Get-ChildItem 命令(别名为 "dir")来预览事务中的更改。

以下命令启动事务。

        start-transaction

以下命令使用 New-ItemProperty cmdlet 将 MyKey 注册表条目添加到 MyCompany 项。该命令使用 UseTransaction 参数将命令包含到事务中。

        new-itemproperty -path MyCompany -Name MyKey -value 123 -UseTransaction

命令返回一个表示新的注册表条目的对象,但是未更改注册表条目。

        MyKey
        -----
        123

若要获取当前位于注册表中的项,则使用没有 UseTransaction 参数的 Get-ChildItem 命令 ("dir")。以下命令获取以 "M." 开头的项

        dir m*

结果显示尚无条目被添加到 MyCompany 项中。

        Hive: HKEY_CURRENT_USER\Software

        SKC  VC Name                           Property
        ---  -- ----                           --------
        83   1 Microsoft                      {(default)}
         0   0 MyCompany                      {}

如要预览提交事务所产生的影响,则输入具有 UseTransaction 参数的 Get-ChildItem ("dir") 命令。此命令可在事务内查看数据。在此处插入部分正文。

        dir m* -useTransaction

结果显示,如果事务已提交,则 MyKey 条目将被添加到 MyCompany 项中。

        Hive: HKEY_CURRENT_USER\Software

        SKC  VC Name                           Property
        ---  -- ----                           --------
        83   1 Microsoft                      {(default)}
         0   1 MyCompany                      {MyKey}

示例 4:将事务处理命令与非事务处理命令结合使用

在事务执行期间,你可以输入非事务处理命令。非事务处理命令会即时影响数据,但不会影响事务。

以下命令启动 HKCU:\Software 注册表项中的事务。

        start-transaction

接下来的三个命令使用 New-Item cmdlet 向注册表添加项。第一个和第三个命令使用 UseTransaction 参数将命令包括在事务中。第二个命令会省略该参数。由于第二个命令不包括在事务中,因此会立即生效。

        new-item MyCompany1 -UseTransaction

        new-item MyCompany2

        new-item MyCompany3 -UseTransaction

如要查看注册表的当前状态,则使用没有 UseTransaction 参数的 Get-ChildItem ("dir") 命令。此命令获取以 "M." 开头的项

        dir m*

结果显示 MyCompany2 项已添加到注册表中,但作为事务一部分的 MyCompany1 和 MyCompany3 项未被添加。

        Hive: HKEY_CURRENT_USER\Software

        SKC  VC Name                           Property
        ---  -- ----                           --------
        83   1 Microsoft                      {(default)}
        0    0 MyCompany2                     {}

以下命令提交事务。

        complete-transaction

现在,作为事务一部分而添加的项出现在注册表中。

        dir m*

     
        Hive: HKEY_CURRENT_USER\Software

        SKC  VC Name                           Property
        ---  -- ----                           --------
        83   1 Microsoft                      {(default)}
        0    0 MyCompany1                     {}
        0    0 MyCompany2                     {}
        0    0 MyCompany3                     {}

示例 5:使用自动回滚

当事务中的命令生成任何类型的错误时,事务将自动回滚。

此默认行为是为运行事务的脚本而设计的。通常情况下,脚本经过良好测试并包括错误处理逻辑,因此不应出现错误,且应终止事务。

第一个命令启动 HKCU:\Software 注册表项中的事务。

        start-transaction

以下命令使用 New-Item cmdlet 将 MyCompany 项添加到注册表。该命令使用 UseTransaction 参数(别名为 "usetx")将命令包括在事务中。

        New-Item MyCompany -UseTX

由于注册表中已存在 MyCompany 项,该命令失败,事务被回滚。

        New-Item : A key at this path already exists
        At line:1 char:9
        + new-item <<<<  MyCompany -usetx

Get-Transaction 命令确定事务已回滚且 SubscriberCount 为 0。

        RollbackPreference   SubscriberCount   Status
        ------------------   ---------------   ------
        Error                0                 RolledBack

示例 6:更改回滚首选项

如果你希望事务具有更高的容错性,可以使用 Start-Transaction 的 RollbackPreference 参数来更改首选项。

以下命令启动回滚首选项为 "Never" 的事务。在此处插入部分正文。

         start-transaction -rollbackpreference Never

在这种情况下,当命令失败时,事务不会自动回滚。

        New-Item MyCompany -UseTX

        New-Item : A key at this path already exists
        At line:1 char:9
        + new-item <<<<  MyCompany -usetx

由于事务仍处于活动状态,你可以将命令作为事务的一部分重新提交。

        New-Item MyOtherCompany -UseTX

示例 7:使用 Use-Transaction cmdlet

Use-Transaction cmdlet 使你能够针对支持事务的 Microsoft .NET Framework 对象直接执行脚本编写。Use-Transaction 采用可只包含命令和表达式(使用支持事务的 .NET Framework 对象)的脚本块,例如,Microsoft.PowerShell.Commands.Management.TransactedString 类的实例。

以下命令启动事务。

         start-transaction

以下 New-Object 命令创建 TransactedString 类的实例,并将其保存在 $t 变量中。

         $t = New-Object Microsoft.PowerShell.Commands.Management.TransactedString

以下命令使用 TransactedString 对象的 Append 方法将文本添加到字符串。由于该命令不是事务的一部分,因此所做更改将立即生效。

        $t.append("Windows")

以下命令使用相同的 Append 方法添加文本,但该命令将文本添加为事务的一部分。命令括在大括号中,并设为 Use-Transaction 的 ScriptBlock 参数的值。需要 UseTransaction 参数 (UseTx)。

        use-transaction {$t.append(" PowerShell")} -usetx

若要查看 $t 中的事务处理字符串的当前内容,则使用 TransactedString 对象的 ToString 方法。

        $t.tostring()

输出显示仅非事务处理更改有效。

        Windows

若要从事务内部查看 $t 中事务处理字符串的当前内容,则将表达式嵌入 Use-Transaction 命令中。

        use-transaction {$s.tostring()} -usetx

输出显示事务视图。

        Windows PowerShell

以下命令提交事务。

        complete-transaction

若要查看最终字符串:

        $t.tostring()

        Windows PowerShell

示例 7:管理多订阅者事务

当你在另一事务正在执行时启动一个事务,默认情况下,Windows PowerShell 不会创建第二个的事务。反之,它会向当前事务添加一个订阅者。

此示例显示如何查看并管理多订阅者事务。

通过启动 HKCU:\Software 项中的事务开始。

        start-transaction

以下命令使用 Get-Transaction 命令获取活动事务。

        get-transaction

结果显示表示活动事务的对象。

        RollbackPreference   SubscriberCount   Status
        ------------------   ---------------   ------
        Error                1                 Active

以下命令将 MyCompany 项添加到注册表中。该命令使用 UseTransaction 参数将命令包括在事务中。

        new-item MyCompany -UseTransaction

以下命令使用 Start-Transaction 命令启动事务。虽然是在命令提示符处键入此命令,但这一情况更有可能在运行包含事务的脚本时发生。

        start-transaction

Get-Transaction 命令显示事务对象上的订阅者计数递增。值现在是 2。

        RollbackPreference   SubscriberCount   Status
        ------------------   ---------------   ------
        Error                2                 Active

下一命令使用 New-ItemProperty cmdlet 将 MyKey 注册表条目添加到 MyCompany 项。该命令使用 UseTransaction 参数将命令包括在事务中。

        new-itemproperty -path MyCompany -name MyKey -UseTransaction

MyCompany 项不存在于注册表中,但此命令会成功是因为两个命令均为同一事务的一部分。

以下命令提交事务。如果它回滚事务,则会为所有订阅者回滚事务。

        complete-transaction

Get-Transaction 命令显示事务对象上的订阅者计数为 1,但 Status 的值仍为 Active(而不是 Committed)。

        RollbackPreference   SubscriberCount   Status
        ------------------   ---------------   ------
        Error                1                 Active

若要完成提交事务,则输入第二个 Complete-Transaction 命令。若要提交多订阅者事务,则必须为每个 Start-Transaction 命令输入一条 Complete-Transaction 命令。

        complete-transaction

另一条 Get-Transaction 命令显示事务已提交。

        RollbackPreference   SubscriberCount   Status
        ------------------   ---------------   ------
        Error                0                 Committed

示例 8:管理独立事务

当你在另一事务正在执行时启动一个事务,你可以使用 Start-Transaction 的 Independent 参数使新的事务独立于原始事务。

当你执行此操作时,Start-Transaction 会创建新的事务对象并让新的事务成为活动事务。

通过启动 HKCU:\Software 项中的事务开始。

        start-transaction

以下命令使用 Get-Transaction 命令获取活动事务。

        get-transaction

结果显示表示活动事务的对象。

        RollbackPreference   SubscriberCount   Status
        ------------------   ---------------   ------
        Error                1                 Active

以下命令将 MyCompany 注册表项添加为该事务的一部分。该命令使用 UseTransaction 参数 (UseTx) 将命令包括在活动事务中。

        new-item MyCompany -use

以下命令启动新的事务。此命令使用 Independent 参数指示此事务不是活动事务的订阅者。

         start-transaction -independent

当你创建一个独立事务时,新的(最近创建的)事务将变为活动事务。你可以使用 Get-Transaction 命令获取活动事务。

        get-transaction

请注意,事务的 SubscriberCount 为 1,指示没有其他订阅者且事务是新的。

        RollbackPreference   SubscriberCount   Status
        ------------------   ---------------   ------
        Error                1                 Active

必须先完成新事务(已提交或已回滚)才能管理原始事务。

以下命令将 MyOtherCompany 项添加到注册表中。该命令使用 UseTransaction 参数 (UseTx) 将命令包括在活动事务中。

        new-item MyOtherCompany -usetx

现在,回滚事务。如果存在具有两个订阅者的单个事务,回滚事务这一操作将为所有订阅者回滚整个事务。

然而,由于这些事务是独立的,回滚最近的事务会取消注册表更改并使原始事务变成活动事务。

        undo-transaction

Get-Transaction 命令确认原始事务在会话中仍然处于活动状态。

        get-transaction
        RollbackPreference   SubscriberCount   Status
        ------------------   ---------------   ------
        Error                1                 Active

以下命令提交活动事务。

        complete-transaction

Get-ChildItem 命令显示注册表已更改。

        dir m*


        Hive: HKEY_CURRENT_USER\Software

        SKC  VC Name                           Property
        ---  -- ----                           --------
        83   1 Microsoft                      {(default)}
         0   0 MyCompany                      {}

另请参阅

Start-Transaction

Get-Transaction

Complete-Transaction

Undo-Transaction

Use-Transaction

Registry(提供程序)

about_Providers

Get-PSProvider

Get-ChildItem