about_Transactions

主题
    about_Transactions

简短说明
    介绍如何管理 Windows PowerShell 中的事务处理操作。

详细说明
    Windows PowerShell 从 Windows PowerShell 2.0 开始支持事务。利用此功能,您可以启动事
    务,指示哪些命令包含在事务中,以及提交或回滚事务。
    
    
  关于事务

      在 Windows PowerShell 中,事务是作为一个逻辑单元进行管理的一个或多个命令的集合。可以完
      成("提交")一个事务,此操作将更改受事务影响的数据。也可以完全撤消("回滚")一个事务,这
      样受影响的数据不会被事务更改。

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

      事务广泛用于数据处理中,特别是数据库操作中的处理和财务交易记录处理。事务最常用于以下这种情况:
      一组命令的最坏情形并非所有命令都失败,而是部分命令成功而其他命令失败,从而使系统处于难以修复的
      损坏、错误或无法解释的状态。

            
  事务 CMDLET

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

      Cmdlet                 说明
      --------------         ---------------------------------   
      Start-Transaction      启动一个新事务。

      Use-Transaction        向事务中添加命令或表达式。添加的命令必须使用支持事务的对象。

      Undo-Transaction       回滚事务,以便任何数据都不会被事务更改。

      Complete-Transaction   提交事务。受事务影响的数据将被更改。

      Get-Transaction        获取有关活动事务的信息。


      要获取事务 cmdlet 的列表,请键入:

          get-command *transaction

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

      get-help <cmdlet-name> -detailed

      例如:
    
      get-help use-transaction -detailed


  支持事务的元素

      若要参与一个事务,cmdlet 和提供程序必须都支持该事务。此功能内置于受事务影响的对象中。
   
      Windows PowerShell Registry 提供程序支持 Windows Vista 中的事务。
      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。
    由于该 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。
    由于该 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(未提交)。


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


    若要完成事务的提交,请再输入一个 Complete-Transaction 命令。若要提交多订阅者事务,必须为
    每个 Complete-Transaction 命令都输入一个 Start-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 -usetx


    下面的命令启动一个新事务。该命令使用 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 (provider)
    about_Providers
    Get-PSProvider
    Get-ChildItem