Tranzakciónak hívjuk a logikailag összetartozó olyan műveletsort, amely vagy együttesen végrehajtásra kerül, vagy ha valami probléma adódik a műveletsor közben, akkor vissza lehet állni a műveletsor megkezdése előtti állapotba. Ráadásul a tranzakció közben a „félkész” műveletsor nem látható a rendszer többi eleme számára, így nem okoz számukra nem teljesen kitöltött adatsor problémát. Az SQL adatbázis-kezelőknél ez már régóta ismert lehetőség, de egyéb adattárakon is hasznos segítőnk lehet.
Emlékeztetőül, vessünk egy pillantást a PSProviderek listájára:
[1] PS C:\> Get-PSProvider
Name Capabilities Drives
---- ------------ ------
WSMan Credentials {WSMan}
Alias ShouldProcess {Alias}
Environment ShouldProcess {Env}
FileSystem Filter, ShouldProcess {C, A, D}
Function ShouldProcess {Function}
Registry ShouldProcess, Transactions {HKLM, HKCU}
Variable ShouldProcess {Variable}
Certificate ShouldProcess {cert}
A Registry provider az egyetlen jelenleg, ami támogatja a tranzakciókat, ráadásul csak Windows Vista / Windows Server 2008 és újabb operációs rendszereken. A gyakorlatban tehát ezzel a lehetőséggel több registry módosítást összefoghatunk egy tranzakcióba, és vagy az egészet egyben végrehajtatjuk, vagy ha valami gond adódik, akkor vissza tudjuk görgetni az egészet olyan állapotba, amikor még semmilyen változtatást nem tettünk a registryben. Ezzel fáradságos takarítási munkától óv meg minket a rendszer.
Egy időben a registryben több tranzakciót is indíthatunk, azonban mindig csak a legutóbb nyitott tranzakciókban lehet műveleteket végrehajtani, ez az un. aktív tranzakció. Korábban megnyitott tranzakcióban dolgozni csak akkor tudunk, ha a legújabbat vagy visszagörgetjük a kiinduló állapotba, vagy befejezzük.
Várhatólag későbbi PowerShell verziókban majd további providerekre is ki lesz terjesztve ez a tranzakcionálási lehetőség. Nézzük, hogy milyen cmdletek állnak rendelkezésünkre most ebben témában:
[2] PS C:\> Get-Command -noun transaction
CommandType Name Definition
----------- ---- ----------
Cmdlet Complete-Transaction Complete-Transaction [-Verb...
Cmdlet Get-Transaction Get-Transaction [-Verbose] ...
Cmdlet Start-Transaction Start-Transaction [-Timeout...
Cmdlet Undo-Transaction Undo-Transaction [-Verbose]...
Cmdlet Use-Transaction Use-Transaction [-Transacte...
Tranzakcióban csak erre alkalmas cmdletekkel lehet műveleteket végezni, ezek olyan cmdletek, melyeknek van –UseTransaction kapcsoló paramétere:
[7] PS C:\> get-help * -Parameter UseTransaction | Get-Command | Sort-Object no
un
CommandType Name Definition
----------- ---- ----------
Cmdlet Get-Acl Get-Acl [[-Path] <String[]>...
Cmdlet Set-Acl Set-Acl [-Path] <String[]> ...
Cmdlet Get-ChildItem Get-ChildItem [[-Path] <Str...
Cmdlet Set-Content Set-Content [-Path] <String...
Cmdlet Get-Content Get-Content [-Path] <String...
Cmdlet Add-Content Add-Content [-Path] <String...
Cmdlet Clear-Content Clear-Content [-Path] <Stri...
Cmdlet Remove-Item Remove-Item [-Path] <String...
Cmdlet New-Item New-Item [-Path] <String[]>...
Cmdlet Get-Item Get-Item [-Path] <String[]>...
Cmdlet Set-Item Set-Item [-Path] <String[]>...
Cmdlet Clear-Item Clear-Item [-Path] <String[...
Cmdlet Invoke-Item Invoke-Item [-Path] <String...
Cmdlet Rename-Item Rename-Item [-Path] <String...
Cmdlet Copy-Item Copy-Item [-Path] <String[]...
Cmdlet Move-Item Move-Item [-Path] <String[]...
Cmdlet Move-ItemProperty Move-ItemProperty [-Path] <...
Cmdlet Remove-ItemProperty Remove-ItemProperty [-Path]...
Cmdlet Get-ItemProperty Get-ItemProperty [-Path] <S...
Cmdlet Rename-ItemProperty Rename-ItemProperty [-Path]...
Cmdlet New-ItemProperty New-ItemProperty [-Path] <S...
Cmdlet Copy-ItemProperty Copy-ItemProperty [-Path] <...
Cmdlet Set-ItemProperty Set-ItemProperty [-Path] <S...
Cmdlet Clear-ItemProperty Clear-ItemProperty [-Path] ...
Cmdlet Set-Location Set-Location [[-Path] <Stri...
Cmdlet Pop-Location Pop-Location [-PassThru] [-...
Cmdlet Get-Location Get-Location [-PSProvider <...
Cmdlet Push-Location Push-Location [[-Path] <Str...
Cmdlet Resolve-Path Resolve-Path [-Path] <Strin...
Cmdlet Convert-Path Convert-Path [-Path] <Strin...
Cmdlet Join-Path Join-Path [-Path] <String[]...
Cmdlet Test-Path Test-Path [-Path] <String[]...
Cmdlet Split-Path Split-Path [-Path] <String[...
Cmdlet Get-PSDrive Get-PSDrive [[-Name] <Strin...
Cmdlet Remove-PSDrive Remove-PSDrive [-Name] <Str...
Cmdlet New-PSDrive New-PSDrive [-Name] <String...
Cmdlet Use-Transaction Use-Transaction [-Transacte...
Látható, hogy ez nem is olyan kicsi lista!
Kezdjünk is el mindjárt egy tranzakciót a Start-Transaction cmdlettel:
[8] PS C:\> Start-Transaction
Suggestion [1,Transactions]: Once a transaction is started, only commands that
get called with the -UseTransaction flag become part of that transaction.
[9] PS C:\> Get-Transaction
RollbackPreference SubscriberCount Status
------------------ --------------- ------
Error 1 Active
A [8]-as sor végrehajtása után kapjuk is a figyelmeztetést, hogy a tranzakcióban csak azok a műveletek fognak részt venni, amelyeknél használjuk a kapcsolót. Visszaolvasva a tranzakciókat a Get-Transaction cmdlettel látható, hogy ez az aktív tranzakció, és egy helyről indítottam el (egy Subscriber, azaz előfizetője van) és automatikusan visszagördítődik a tranzakció, ha valamilyen hiba lép fel. Ezt a RollbackPreference tulajdonság írja le, amelyet át is lehet írni, ha a Start-Transaction-t a megfelelően megadott ‑RollBackPreference paraméterrel hívjuk meg. A lehetséges értékek: Error, TerminatingError és Never.
Ugyancsak szabályozni lehet a tranzakciók automatikus visszaállását a Start-Transaction ‑TimeOut paraméterével, ami alaphelyzetben az interaktívan indított tranzakcióknál nincsen, viszont a szkriptekből indított tranzakciók esetében 30 percig engedi a lezáratlan tranzakciókat létezni, utána automatikusan visszaállít.
Használjuk az előbb indított tranzakciót! Létrehozok egy elemet:
[12] PS C:\> New-Item 'HKCU:\Software\soostibi' -UseTransaction
Hive: HKEY_CURRENT_USER\Software
SKC VC Name Property
--- -- ---- --------
0 0 soostibi {}
[13] PS C:\> Get-Item 'HKCU:\Software\soostibi'
Get-Item : Cannot find path 'HKCU:\Software\soostibi'
because it does not exis
t.
At line:1 char:9
+ Get-Item <<<< 'HKCU:\Software\soostibi'
+
CategoryInfo : ObjectNotFound:
(HKCU:\Software\soostibi:String
)
[Get-Item], ItemNotFoundException
+
FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetI
temCommand
[14] PS C:\> Get-Item 'HKCU:\Software\soostibi' -UseTransaction
Hive: HKEY_CURRENT_USER\Software
SKC VC Name Property
--- -- ---- --------
0 0 soostibi {}
Tehát létrehoztam egy „soostibi” nevű elemet a registry HKCU/Software ágában. Mikor visszaolvastam ezt a Get-Item cmdlettel ([13]-as sor), akkor hibát kaptam, hiszen itt nem használtam a –UseTransaction paramétert és a tranzakción belüli műveletek a külvilág számára nem látszanak. Amikor már használtam ezt a kapcsolót a [14]-es sorban, akkor természetesen már látható volt a létrehozott elem.
Ha minden egyéb körülménnyel meg vagyok elégedve, akkor lezárhatom a tranzakciót a Complete-Transaction cmdlettel, és ha ekkor olvasom vissza a registry kulcsot „normál” módon, akkor már látható az imént felvett elem:
[15] PS C:\> Complete-Transaction
[16] PS C:\> Get-Item 'HKCU:\Software\soostibi'
Hive: HKEY_CURRENT_USER\Software
SKC VC Name Property
--- -- ---- --------
0 0 soostibi {}
Természetesen az Undo-Transaction segítségével semmissé lehetett volna tenni a tranzakciót. Ugyanígy semmissé válik egy tranzakció a már korábban említett hibajelenségekkor, vagy ha bizonyos ideig nem zárjuk le.
Ha a tranzakciót lezártuk, vagy semmissé tettük, akkor is lekérdezhető az állapota:
[15] PS C:\> Get-Transaction
RollbackPreference SubscriberCount Status
------------------ --------------- ------
Error 0 Committed
A Status tulajdonság mutatja, hogy milyen módon fejeződött be.
Ha többször is kiadjuk a Start-Transaction cmdletet, akkor alaphelyzetben nem nyílik újabb és újabb tranzakciós környezet, hanem csak az előfizetők száma növekszik. Azaz a tranzakciót használó szkriptek, még ha egymástól függetlenül is indultak el, mégis egy közös tranzakciós terepen dolgoznak. Bármelyikük miatt is történik egy esetleges visszaállás az eredeti helyzetbe, ezt mindegyik előfizető „megérzi”. Ezzel szemben a tranzakciót annyiszor kell lezárni, ahány előfizető van, így a teljes tranzakciós környezet csak akkor zárul sikeresen, ha minden folyamat ehhez hozzájárult.
Ha egymástól független tranzakciós terepeket akarunk nyitni, akkor a Start-Transaction cmdletet az –Independent kapcsolóval hívjuk meg.