about_Transactions

適用対象: Windows PowerShell 2.0, Windows PowerShell 3.0

トピック

about_Transactions

概要

Windows PowerShell® でトランザクション操作を管理する方法について説明します。

詳細説明

トランザクションは、Windows PowerShell 2.0 以降の Windows PowerShell でサポートされています。この機能を使用して、トランザクションの開始、トランザクションに含めるコマンドの指定、トランザクションのコミットまたはロールバックを実行できます。

トランザクションについて

Windows PowerShell では、トランザクションは、論理的な単位として管理される 1 つ以上のコマンドのセットです。トランザクションは完了 ("コミット") することができます。この場合、トランザクションの影響を受けるデータは変更されます。または、トランザクションは完全に元に戻す ("ロールバック") ことができます。この場合、トランザクションの影響を受けるデータは変更されません。

1 つのトランザクション内のコマンドは 1 つの単位として管理されるので、コマンドはすべてコミットされるか、すべてロールバックされるかのいずれかとなります。

トランザクションは、データ処理において広く使用されています。最も顕著なのは、データベース操作や金融取引での使用です。トランザクションが最もよく使用されるのは、一連のコマンドのすべてが失敗することが最悪のシナリオではなく、一部のコマンドは成功するがそれ以外のコマンドは失敗し、システムが修復困難な破損、失敗、または解釈不可能な状態になることが最悪のシナリオである場合です。

トランザクションのコマンドレット

Windows PowerShell には、トランザクションを管理するために設計された複数のコマンドレットが含まれています。

      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.

トランザクションのコマンドレットの一覧を参照するには、次のように入力してください。

          get-command *transaction

コマンドレットに関する詳細については、次のように入力してください。

          get-help <cmdlet-name> -detailed

たとえば、次のように入力します。

          get-help use-transaction -detailed

トランザクション対応の要素

トランザクションに参加するには、コマンドレットとプロバイダーの両方がトランザクションをサポートする必要があります。この機能は、トランザクションの影響を受けるオブジェクトに組み込まれています。

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 パラメーター

トランザクションをサポートできるコマンドレットは UseTransaction パラメーターを備えています。このパラメーターには、アクティブなトランザクションのコマンドが含まれます。パラメーターのフル ネーム、またはそのエイリアスである "usetx" を使用することができます。

パラメーターは、セッションにアクティブなトランザクションが含まれている場合にのみ使用できます。アクティブなトランザクションが存在しない場合に、UseTransaction パラメーターを使用したコマンドを入力すると、そのコマンドは失敗します。

UseTransaction パラメーターを備えたコマンドレットを見つけるには、次のように入力します。

        get-help * -parameter UseTransaction

Windows PowerShell コアでは、Windows PowerShell プロバイダーと共に機能するように設計されたすべてのコマンドレットが、トランザクションをサポートします。そのため、プロバイダー コマンドレットを使用してトランザクションを管理することができます。

Windows PowerShell プロバイダーの詳細については、「about_Providers」を参照してください。

トランザクション オブジェクト

Windows PowerShell では、トランザクションは System.Management.Automation.Transaction というトランザクション オブジェクトによって表されます。

このオブジェクトには、次のプロパティがあります。

RollbackPreference:

現在のトランザクションに設定されたロールバック設定を保持します。Start-Transaction を使用してトランザクションを開始する場合、ロールバック設定を指定できます。

ロールバック設定により、トランザクションが自動的にロールバックされる場合の条件が決まります。有効な値は、Error、TerminatingError、および Never です。既定値は Error です。

Status:

トランザクションの現在の状態を保持します。有効な値は、Active、Committed、および RolledBack です。

SubscriberCount:

トランザクションのサブスクライバーの数を保持します。トランザクションの進行中に、別のトランザクションを開始すると、サブスクライバーがそのトランザクションに追加されます。サブスクライバーがトランザクションをコミットすると、サブスクライバーの数は減少します。

アクティブなトランザクション

Windows PowerShell では、一度に 1 つのトランザクションのみがアクティブになり、アクティブなトランザクションのみを管理することができます。同じセッションで同時に複数のトランザクションが進行中の場合もありますが、アクティブになるのは最後に開始されたトランザクションのみです。

そのため、トランザクション コマンドレットの使用時に特定のトランザクションを指定することはできません。コマンドは、アクティブなトランザクションに常に適用されます。

このことは、Get-Transaction コマンドレットの動作において顕著です。Get-Transaction コマンドを入力した場合、Get-Transaction では常に 1 つのみのトランザクション オブジェクトを取得します。このオブジェクトは、アクティブなトランザクションを表すオブジェクトです。

別のトランザクションを管理するには、最初に、アクティブなトランザクションをコミットまたはロールバックすることによって終了しておく必要があります。終了すると、その前のトランザクションが自動的にアクティブになります。トランザクションは、開始した順序とは逆の順序でアクティブになるので、最後に開始したトランザクションが常にアクティブになります。

サブスクライバーおよび独立したトランザクション

トランザクションの進行中に別のトランザクションを開始しても、既定では、Windows PowerShell は新しいトランザクションを開始しません。代わりに、現在のトランザクションに "サブスクライバー" を追加します。

1 つのトランザクションに複数のサブスクライバーがある場合、任意の時点で 1 つの Undo-Transaction コマンドを使用すると、すべてのサブスクライバーのトランザクション全体がロールバックされます。一方、トランザクションをコミットするには、それぞれのサブスクライバーに対して Complete-Transaction コマンドを入力する必要があります。

トランザクションのサブスクライバーの数を調べるには、トランザクション オブジェクトの SubscriberCount プロパティを確認します。たとえば、次のコマンドは、Get-Transaction コマンドレットを使用して、アクティブなトランザクションの SubscriberCount プロパティの値を取得します。

          (Get-Transaction).SubscriberCount

別のトランザクションの進行中に開始されるトランザクションは、ほとんどの場合が元のトランザクションに関連しているため、サブスクライバーの追加が既定の動作になっています。一般的なモデルでは、トランザクションが含まれたスクリプトは、独自のトランザクションが含まれたヘルパー スクリプトを呼び出します。これらのトランザクションは関連しているため、1 つの単位としてロールバックまたはコミットする必要があります。ここにセクション本体を挿入します。

一方、Start-Transaction コマンドレットの Independent パラメーターを使用することで、現在のトランザクションから独立したトランザクションを開始できます。

独立したトランザクションを開始すると Start-Transaction は新しいトランザクション オブジェクトを作成し、その新しいトランザクションがアクティブなトランザクションになります。独立したトランザクションは、元のトランザクションに影響を与えることなく、コミットまたはロールバックできます。

独立したトランザクションが終了 (コミットまたはロールバック) すると、元のトランザクションが再びアクティブなトランザクションになります。

データの変更

トランザクションを使用してデータを変更する場合、このトランザクションの影響を受けるデータは、トランザクションをコミットするまでは変更されません。ただし、同じデータが、このトランザクションの一部ではないコマンドによって変更される可能性はあります。

トランザクションを使用して共有データを管理する際は、このことに注意してください。通常、データベースには、作業中のデータをロックして、他のユーザーや他のコマンド、スクリプト、関数によって変更されることを回避するメカニズムが備わっています。

ただし、ロックはデータベースの機能です。トランザクションには関係ありません。トランザクション対応のファイル システムまたはその他のデータ ストアで作業している場合、トランザクションの進行中にデータが変更される可能性があります。

このセクションの例では、Windows PowerShell Registry プロバイダーを使用し、このプロバイダーを使い慣れていることを前提としています。Registry プロバイダーの詳細については、「get-help registry」と入力してください。

例 1: トランザクションのコミット

トランザクションを作成するには、Start-Transaction コマンドレットを使用します。次のコマンドは、既定の設定でトランザクションを開始します。

        start-transaction

コマンドをトランザクションに含めるには、コマンドレットの UseTransaction パラメーターを使用します。既定では、コマンドはトランザクションに含まれていません。

たとえば、次のコマンド (現在の場所を HKCU: ドライブの Software キーに設定する) はトランザクションに含まれていません。

        cd hkcu:\Software

次のコマンドは、MyCompany キーを作成します。New-Item コマンドレットの UseTransaction パラメーターを使用して、コマンドをアクティブなトランザクションに含めます。

        new-item MyCompany -UseTransaction

このコマンドは新しいキーを表すオブジェクトを返しますが、コマンドがトランザクションの一部であるため、レジストリはまだ変更されません。

        Hive: HKEY_CURRENT_USER\Software

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

トランザクションをコミットするには、Complete-Transaction コマンドレットを使用します。これはアクティブなトランザクションに常に影響を与えるので、トランザクションを指定することはできません。

        complete-transaction

結果的に、MyCompany キーがレジストリに追加されます。

        dir m*
       
        Hive: HKEY_CURRENT_USER\software

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

例 2: トランザクションのロールバック

トランザクションを作成するには、Start-Transaction コマンドレットを使用します。次のコマンドは、既定の設定でトランザクションを開始します。

        start-transaction

次のコマンドは、MyOtherCompany キーを作成します。New-Item コマンドレットの UseTransaction パラメーターを使用して、コマンドをアクティブなトランザクションに含めます。

        new-item MyOtherCompany -UseTransaction

このコマンドは新しいキーを表すオブジェクトを返しますが、コマンドがトランザクションの一部であるため、レジストリはまだ変更されません。

        Hive: HKEY_CURRENT_USER\Software

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

トランザクションをロールバックするには、Undo-Transaction コマンドレットを使用します。これはアクティブなトランザクションに常に影響を与えるので、トランザクションは指定しません。

        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 コマンドレットを使用して、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

次の 3 つのコマンドは、New-Item コマンドレットを使用して、キーをレジストリに追加します。1 番目と 3 番目のコマンドは、UseTransaction パラメーターを使用して、コマンドをトランザクションに含めます。2 番目のコマンドでは、パラメーターが省略されています。2 番目のコマンドは、トランザクションに含まれていないので、すぐに有効になります。

        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 コマンドレットを使用して、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 コマンドレットの使用

Use-Transaction コマンドレットを使用すると、トランザクション対応の Microsoft .NET Framework オブジェクトに対する直接スクリプトを行うことができます。Use-Transaction では、Microsoft.PowerShell.Commands.Management.TransactedString クラスのインスタンスなど、トランザクション対応の .NET Framework オブジェクトを使用するコマンドと式のみを含めることができるスクリプト ブロックを使用します。

次のコマンドは、トランザクションを開始します。

         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 は 2 番目のトランザクションを作成しません。代わりに、現在のトランザクションにサブスクライバーを追加します。

この例は、マルチサブスクライバー トランザクションを表示および管理する方法を示しています。

最初に 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 コマンドレットを使用して、MyKey レジストリ エントリを MyCompany キーに追加します。このコマンドは、UseTransaction パラメーターを使用して、コマンドをトランザクションに含めます。

        new-itemproperty -path MyCompany -name MyKey -UseTransaction

MyCompany キーはレジストリには存在しませんが、2 つのコマンドが同じトランザクションの一部であるため、このコマンドは成功します。

次のコマンドは、トランザクションをコミットします。コマンドでトランザクションをロールバックすると、トランザクションはすべてのサブスクライバーに対してロールバックされます。

        complete-transaction

Get-Transaction コマンドは、トランザクション オブジェクトにおけるサブスクライバーの数が 1 であるが、Status の値は依然として (Committed ではなく) Active であることを示しています。

        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

ここでは、トランザクションをロールバックします。1 つのトランザクションに 2 つのサブスクライバーが存在する場合、このトランザクションのロールバックでは、すべてのサブスクライバーに対してトランザクション全体をロールバックすることになります。

ただし、トランザクションは独立しているため、最新のトランザクションのロールバックにより、レジストリの変更は取り消され、元のトランザクションがアクティブなトランザクションになります。

        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