应用到: 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