Chapter 30. Transactions

Introduction

Transactions describe a system's ability to support tentative or multi-step changes. When you make changes within the context of a transaction, the system provides four main guarantees:

2 comments

  1. Richard Siddaway Posted 9 days and 23 hours ago

    Reviewing

  2. David "Makovec" Moravec Posted 6 days and 9 hours ago

    Could be good to include note that transactions are available from Vista OS.

Add a comment

  • Isolation: To observers not participating in the transaction, the commands inside the transaction have not impacted the system.

  • Atomicity: Once you decide to finalize (commit) a transaction, either all of the changes take effect, or none of them do.

  • Consistency: Errors caused during a transaction that would cause an inconsistent system state are dealt with in order to bring the system back to a consistent state.

  • Durability: Once the system has informed you of the transaction's successful completion, you can be certain that the changes are permanent.

As a real-world example of a transaction, consider a money transfer between two bank accounts. This might happen in two stages: subtract the money from the first account, and then add the money to the second account. In this situation, you have the exact same goals for robustness and correctness:

1 comment

  1. Richard Siddaway Posted 9 days and 23 hours ago

    Might be worth including a non-technical example of a transaction eg a monetary transfer between bank accounts and link it to the 4 guarantees listed above

Add a comment

  • Isolation: While the money transfer is taking place (but has not yet completed), the balance of both bank accounts appears unchanged.

  • Atomicity: At some point in the process, it's possible that we've subtracted the money from the first account but haven't added it yet to the second account. When we process the money transfer, it's critical that the system never shows this intermediate state. Either all of the changes take effect, or none of them do.

  • Consistency: If an error occurs during the money transfer, the system takes corrective action to ensure that it is not left in an intermediate state. Perhaps it accounts for a lack of funds by adding an overdraft charge, or by abandoning the entire money transfer altogether. It should not, for example, have taken the funds from one account without depositing them into the second account.

  • Durability: Once the money transfer completes, you don't have to worry about a system error undoing all or part of it.

While normally a developer topic, PowerShell exposes transactions as an end-user concept, opening a great deal of potential for consistent system management.

To start a transaction, call the Start-Transaction cmdlet. To use a cmdlet that supports transactions, specify the –UseTransaction parameter. Being explicit about this parameter is crucial, as many cmdlets that support transactions can work equally well without one. Because of that, PowerShell only lets the cmdlet participate in the transaction when you supply this parameter.

In Windows Vista and later, PowerShell’s registry provider supports transactions as a first-class concept. You can see this in action in the section called “Safely Combine Related Registry Modifications”,

PS > Set-Location HKCU:
PS > Start-Transaction

PS > mkdir TempKey -UseTransaction

    Hive: HKEY_CURRENT_USER

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

PS > New-Item TempKey\TempKey2 -UseTransaction


    Hive: HKEY_CURRENT_USER\TempKey

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

PS > Get-ChildItem TempKey
Get-ChildItem : Cannot find path 'HKEY_CURRENT_USER\TempKey' because it do
es not exist.

PS > Complete-Transaction
PS > Get-ChildItem TempKey

    Hive: HKEY_CURRENT_USER\TempKey

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

Once you have completed the transactional work, call the Complete-Transaction cmdlet to make it final, or the Undo-Transaction cmdlet to discard the changes. While you may now be tempted to experiment with transactions on other providers (for example, the filesystem), be aware that only the registry provider currently supports them.

Safely Experiment With Transactions

Problem

You want to experiment with PowerShell's transactions support, but don't want to use the Registry Provider as your playground.

1 comment

  1. Aleksandar Nikolic Posted 16 days and 20 hours ago

    suport --> support

Add a comment

Solution

Use PowerShell's System.Management.Automation.TransactedString object along with the Use-Transaction cmdlet to experiment with a string, rather than registry keys:

2 comments

  1. Richard Siddaway Posted 9 days and 22 hours ago

    Do we get any information on other .NET classes that support transactions

  2. Lee Holmes Posted 7 days and 22 hours ago

    I thought about that, but it seems a bit too much for most to chew. Our goal was not to introduce transacted .NET scripting to the masses, but to support transacted scripting for developers that could previously only do this through compiled .NET languages.

Add a comment

PS > Start-Transaction

Suggestion [1,Transactions]: Once a transaction is started, only commands that
 get called with the -UseTransaction flag become part of that transaction.
PS > 
PS > $transactedString = New-Object Microsoft.PowerShell.Commands.Management.Tra
nsactedString
PS > $transactedString.Append("Hello ")
PS > 
PS > Use-Transaction -UseTransaction { $transactedString.Append("World") }

Suggestion [2,Transactions]: The Use-Transaction cmdlet is intended for script
ing of transaction-enabled .NET objects. Its ScriptBlock should contain nothin
g else.
PS > 
PS > $transactedString.ToString()
Hello
PS > 
PS > Complete-Transaction
PS > 
PS > $transactedString.ToString()
Hello World
PS > 

Discussion

PowerShell's transaction support builds on four core cmdlets: Start-Transaction, Use-Transaction, Complete-Transaction, and Undo-Transaction.

The Start-Transaction begins a transaction, creating a context where changes are visible to commands within the transaction, but not outside of it. For the most part, after starting a transaction, you'll apply commands to that transaction by adding the -UseTransaction to a cmdlet that supports it. For example, when a PowerShell provider supports transactions, all of PowerShell's core cmdlets (Get-ChildItem, Remove-Item, etc), let you specify the -UseTransaction parameter for actions against that provider.

The Use-Transaction cmdlet is slightly different. While it still requires the -UseTransaction parameter to apply its script block to the current transaction, its sole purpose is to let you script against .NET objects that support transactions themselves. Since they have no way to supply a -UseTransaction parameter, PowerShell offers this generic cmdlet for any type of transactional .NET scripting.

1 comment

  1. Richard Siddaway Posted 9 days and 22 hours ago

    do ADO.NET transactions work with this method?

Add a comment

Note

Other transaction-enabled cmdlets should not be called within the Use-Transaction script block. You'll still need to provide the -UseTransaction parameter to the cmdlet being called, and there's a chance that they might cause instability with your PowerShell-wide transactions.

To give users an opportunity to play with something a little less risky than the Windows Registry, PowerShell includes the Microsoft.PowerShell.Commands.Management.TransactedString class. This class acts like you'd expect any transacted command to act, and lets you become familiar with how the rest of PowerShell's transaction cmdlets work together. Since this is a .NET object, it must be called from within the script block of the Use-Transaction cmdlet.

Finally, when you are finished performing tasks for the current transaction, call either the Complete-Transaction or Undo-Transaction cmdlets. As compared to the solution, here's an example session where the Undo-Transaction cmdlet lets you discard changes made during the transaction:

PS > Start-Transaction

Suggestion [1,Transactions]: Once a transaction is started, only commands that
 get called with the -UseTransaction flag become part of that transaction.
PS > 
PS > $transactedString = New-Object Microsoft.PowerShell.Commands.Management.Tra
nsactedString
PS > $transactedString.Append("Hello ")
PS > 
PS > Use-Transaction -UseTransaction { $transactedString.Append("World") }

Suggestion [2,Transactions]: The Use-Transaction cmdlet is intended for script
ing of transaction-enabled .NET objects. Its ScriptBlock should contain nothin
g else.
PS > 
PS > $transactedString.ToString()
Hello
PS > 
PS > Undo-Transaction
PS > 
PS > $transactedString.ToString()
Hello

1 comment

  1. AndrewTearle Posted 16 days and 8 hours ago

    Suggestion [2,Transactions]: The Use-Transaction cmdlet is intended for script ing of transaction-enabled .NET objects. Its ScriptBlock should contain nothin g else. PS> PS>$transactedString.ToString() Hello PS> PS>Undo-Transaction PS> PS>$transactedString.ToString() Hello ( A little obscure perhaps ? )

Add a comment

For more information about transactions in the Windows Registry, see the section called “Safely Combine Related Registry Modifications”.

Change Error Recovery Behavior in Transactions

Problem

You want to change how PowerShell responds to errors during the execution of a transacted cmdlet.

Solution

Use the -RollbackPreference parameter of the Start-Transaction cmdlet to control what type of error will cause PowerShell to automatically undo your transaction:

HKCU:\ >Start-Transaction
HKCU:\ >New-Item Foo -UseTransaction

    Hive: HKEY_CURRENT_USER

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

HKCU:\ >Copy IDoNotExist Foo -UseTransaction
Copy-Item : Cannot find path 'HKCU:\IDoNotExist' because it does not exist.

HKCU:\ >Complete-Transaction
Complete-Transaction : Cannot commit transaction. The transaction has been ro
lled back or has timed out.

HKCU:\ >Start-Transaction -RollbackPreference TerminatingError

    Hive: HKEY_CURRENT_USER

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

HKCU:\ >Copy IDoNotExist Foo -UseTransaction
Copy-Item : Cannot find path 'HKCU:\IDoNotExist' because it does not exist.

HKCU:\ >Complete-Transaction
HKCU:\ >Get-Item Foo

    Hive: HKEY_CURRENT_USER

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

Discussion

Errors in scripts are an extremely frequent cause of system inconsistency. If a script incorrectly assumes the existence of a registry key or other system state, this type of error tends to waterfall through the entire script. As the script continues, some of the operations succeed, while others fail. When the script completes, you're in a difficult situation in not knowing exactly what portions of the script worked correctly.

Sometimes, running the script again will magically make the problems go away. Unfortunately, it's just as common to have a painstaking manual cleanup effort facing you.

Addressing these consistency issues is one of the primary goals of system transactions.

When PowerShell creates a new transaction, it undoes (rolls back) your transaction for any error it encounters that is operating in the context of that transaction. When PowerShell rolls back your transaction, the system impact is clear: no part of your transaction was made permanent, so your system is still entirely consistent.

Some situations are simply too volatile to be able to depend on this rigid interpretation of consistency, though, so PowerShell offers the -RollbackPreference parameter on the Start-Transaction to let you configure how it should respond to errors:

1 comment

  1. AndrewTearle Posted 16 days and 8 hours ago

    Some situations are simply to volatile ( too )

Add a comment

For more information about PowerShell's error handling and error levels, see Chapter 15, Tracing and Error Management.

You must sign in or register before commenting
*
*
*
*
*

Atom Icon Comments on this page or Comments on the whole book.