概要
PowerShell でトランザクション操作を管理する方法について説明します。
詳細説明
トランザクションは、PowerShell 2.0 以降の PowerShell でサポートされています。 この機能を使用すると、トランザクションの開始、トランザクションの一部であるコマンドの指定、トランザクションのコミットまたはロールバックを行うことができます。
取引について
PowerShell では、トランザクションは論理ユニットとして管理される 1 つ以上のコマンドのセットです。 トランザクションを完了 ("コミット") すると、トランザクションの影響を受けるデータが変更されます。 または、トランザクションを完全に元に戻す ("ロールバック") して、影響を受けるデータがトランザクションによって変更されないようにすることもできます。
トランザクション内のコマンドは 1 つの単位として管理されるため、すべてのコマンドがコミットされるか、すべてのコマンドがロールバックされます。
トランザクションは、データ処理で広く使用されています。特に、データベース操作や金融トランザクションで使用されます。 トランザクションは、一連のコマンドの最悪のシナリオが、すべてのコマンドが失敗するのではなく、一部のコマンドが成功し、他のコマンドが失敗するため、システムが損傷した状態、誤った状態、または修復が困難な解釈不能な状態になる場合に最もよく使用されます。
トランザクション コマンドレット
PowerShell には、トランザクションを管理するために設計されたいくつかのコマンドレットが含まれています。
- Start-Transaction: 新しいトランザクションを開始します。
- Use-Transaction: トランザクションにコマンドまたは式を追加します。 このコマンドでは、トランザクションが有効なオブジェクトを使用する必要があります。
- Undo-Transaction: トランザクションによってデータが変更されないように、トランザクションをロールバックします。
- Complete-Transaction: トランザクションをコミットします。 トランザクションの影響を受けるデータが変更されます。
- Get-Transaction: アクティブなトランザクションに関する情報を取得します。
トランザクション コマンドレットの一覧については、次のように入力します。
get-command *transaction
コマンドレットの詳細については、次のように入力します。
get-help use-transaction -detailed
TRANSACTION-ENABLED 要素
トランザクションに参加するには、コマンドレットとプロバイダーの両方でトランザクションをサポートする必要があります。 この機能は、トランザクションの影響を受けるオブジェクトに組み込まれています。
PowerShell レジストリ プロバイダーは、Windows Vista でのトランザクションをサポートしています。 TransactedString オブジェクト (Microsoft.PowerShell.Commands.Management.TransactedString) は、PowerShell を実行するすべてのオペレーティング システムで動作します。
他の PowerShell プロバイダーはトランザクションをサポートできます。 セッション内でトランザクションをサポートする 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
PowerShell コアでは、PowerShell プロバイダーと連携するように設計されたすべてのコマンドレットがトランザクションをサポートします。 その結果、プロバイダー コマンドレットを使用してトランザクションを管理できます。
PowerShell プロバイダーの詳細については、「about_Providers」を参照してください。
TRANSACTION オブジェクト
トランザクションは、PowerShell ではトランザクション オブジェクト System.Management.Automation.Transaction によって表されます。
オブジェクトには、次のプロパティがあります。
RollbackPreference: 現在のトランザクションに設定されたロールバック設定が含まれます。 ロールバックの設定は、Start-Transaction を使用してトランザクションを開始するときに設定できます。
ロールバック設定によって、トランザクションが自動的にロールバックされる条件が決まります。 有効な値は、Error、TerminatingError、および Never です。 デフォルト値は Error です。
ステータス: トランザクションの現在のステータスが含まれます。 有効な値は、Active、Committed、および RolledBack です。
SubscriberCount: トランザクションのサブスクライバーの数が含まれます。 別のトランザクションの進行中にトランザクションを開始すると、サブスクライバーがトランザクションに追加されます。 サブスクライバーがトランザクションをコミットすると、サブスクライバー数が減少します。
アクティブなトランザクション
PowerShell では、一度にアクティブなトランザクションは 1 つだけであり、アクティブなトランザクションのみを管理できます。 同じセッションで複数のトランザクションを同時に進行中にできますが、アクティブなのは最後に開始されたトランザクションだけです。
そのため、トランザクション コマンドレットを使用するときに特定のトランザクションを指定することはできません。 コマンドは常にアクティブなトランザクションに適用されます。
これは、Get-Transaction コマンドレットの動作に最も顕著に表れています。 Get-Transaction コマンドを入力すると、Get-Transaction は常に 1 つのトランザクションオブジェクトのみを取得します。 このオブジェクトは、アクティブなトランザクションを表すオブジェクトです。
別のトランザクションを管理するには、最初にアクティブなトランザクションをコミットするかロールバックして完了する必要があります。 これを行うと、前のトランザクションが自動的にアクティブになります。 トランザクションは、開始された順序とは逆の順序でアクティブになるため、最後に開始されたトランザクションが常にアクティブになります。
サブスクライバーと独立したトランザクション
別のトランザクションの進行中にトランザクションを開始した場合、既定では、PowerShell は新しいトランザクションを開始しません。 代わりに、現在のトランザクションに "サブスクライバー" が追加されます。
トランザクションに複数のサブスクライバーがある場合、任意の時点で 1 つの Undo-Transaction コマンドを実行すると、すべてのサブスクライバーのトランザクション全体がロールバックされます。 ただし、トランザクションをコミットするには、すべてのサブスクライバーに対して Complete-Transaction コマンドを入力する必要があります。
トランザクションのサブスクライバー数を調べるには、トランザクション オブジェクトの SubscriberCount プロパティを確認します。 たとえば、次のコマンドでは、Get-Transaction コマンドレットを使用して、アクティブなトランザクションの SubscriberCount プロパティの値を取得します。
(Get-Transaction).SubscriberCount
サブスクライバーの追加は、別のトランザクションの進行中に開始されるほとんどのトランザクションが元のトランザクションに関連しているため、既定の動作です。 一般的なモデルでは、トランザクションを含むスクリプトは、独自のトランザクションを含むヘルパー スクリプトを呼び出します。 トランザクションは関連しているため、ロールバックするか、ユニットとしてコミットする必要があります。
ただし、Start-Transaction コマンドレットの Independent パラメーターを使用して、現在のトランザクションから独立したトランザクションを開始できます。
独立したトランザクションを開始すると、Start-Transaction によって新しいトランザクション オブジェクトが作成され、新しいトランザクションがアクティブ トランザクションになります。 独立したトランザクションは、元のトランザクションに影響を与えずにコミットまたはロールバックできます。
独立したトランザクションが完了 (コミットまたはロールバック) されると、元のトランザクションが再びアクティブなトランザクションになります。
データの変更
トランザクションを使用してデータを変更する場合、トランザクションの影響を受けるデータは、トランザクションをコミットするまで変更されません。 ただし、トランザクションの一部ではないコマンドによって同じデータを変更できます。
トランザクションを使用して共有データを管理する場合は、この点に注意してください。 通常、データベースには、作業中にデータをロックするメカニズムがあり、他のユーザーや他のコマンド、スクリプト、および関数が変更されないようにします。
ただし、ロックはデータベースの機能です。 取引とは関係ありません。 トランザクションが有効なファイル システムまたはその他のデータ ストアで作業している場合は、トランザクションの進行中にデータを変更できます。
例の数々
このセクションの例では、PowerShell レジストリ プロバイダーを使用し、理解していることを前提としています。 レジストリ プロバイダの詳細については、「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: トランザクション・コマンドと NON-TRANSACTED コマンドの組み合わせ
トランザクション中に、トランザクション以外のコマンドを入力できます。 非トランザクション コマンドは、データにすぐに影響しますが、トランザクションには影響しません。 次のコマンドは、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
出力には、トランザクション ビューが表示されます。
PowerShell
次のコマンドは、トランザクションをコミットします。
complete-transaction
最後の文字列を表示するには:
$t.tostring()
PowerShell
例 8: MULTI-SUBSCRIBER トランザクションの管理
別のトランザクションの進行中にトランザクションを開始した場合、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の値は依然としてアクティブです(コミットされていません)。
RollbackPreference SubscriberCount Status
------------------ --------------- ------
Error 1 Active
トランザクションのコミットを完了するには、2 つ目の Complete- Transaction コマンドを入力します。 マルチサブスクライバー・トランザクションをコミットするには、Start-Transaction・コマンドごとに 1 つの Complete-Transaction コマンドを入力する必要があります。
complete-transaction
別の Get-Transaction コマンドは、トランザクションがコミットされたことを示します。
RollbackPreference SubscriberCount Status
------------------ --------------- ------
Error 0 Committed
例 9: 独立トランザクションの管理
別のトランザクションの進行中にトランザクションを開始する場合は、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
次に、トランザクションをロールバックします。 サブスクライバーが 2 つのトランザクションが 1 つある場合、トランザクションをロールバックすると、すべてのサブスクライバーのトランザクション全体がロールバックされます。
ただし、これらのトランザクションは独立しているため、最新のトランザクションをロールバックすると、レジストリの変更が取り消され、元のトランザクションがアクティブなトランザクションになります。
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 {}