РАЗДЕЛ about_Transactions КРАТКОЕ ОПИСАНИЕ Описание способов управления операциями транзакций в Windows PowerShell. ПОЛНОЕ ОПИСАНИЕ Транзакции поддерживаются в Windows PowerShell начиная с версии Windows PowerShell 2.0. Эта функция позволяет начинать транзакции, указывать команды, входящие в транзакции, и фиксировать или откатывать транзакции. О ТРАНЗАКЦИЯХ Транзакция в Windows PowerShell - это набор из одной или нескольких команд, которыми можно управлять как логическим блоком. При выполнении ("фиксации") транзакции изменяются данные, на которые повлияла транзакция. Транзакцию также можно полностью отменить ("откатить"), не изменяя этой транзакцией данные, на которые она могла бы повлиять. Поскольку команды в транзакции рассматриваются как единый блок, либо все команды фиксируются, либо все команды откатываются. Транзакции широко используются в обработке данных, особенно при операциях с базами данных и для финансовых транзакций. Чаще всего транзакции используются, если худшим вариантом для набора команд является не ошибка всех команд, а успешное выполнение лишь части из них, сопровождаемое ошибками других, приводящими систему в поврежденное, некорректное или нечитаемое состояние, которое трудно исправить. КОМАНДЛЕТЫ ДЛЯ ТРАНЗАКЦИЙ В Windows PowerShell включено несколько командлетов, предназначенных для работы с транзакциями. Командлет Описание -------------- --------------------------------- Start-Transaction Запускает новую транзакцию. Use-Transaction Добавляет в транзакцию команду или выражение. Команда должна использовать объекты, поддерживающие транзакции. Undo-Transaction Откатывает транзакцию, не изменяя транзакцией данные. Complete-Transaction Фиксирует транзакцию. Изменяет данные, на которые влияет транзакция. Get-Transaction Возвращает сведения об активной транзакции. Чтобы вывести список командлетов транзакции, введите следующую команду: get-command *transaction Чтобы получить дополнительные сведения о командлетах, введите следующую команду: get-help <имя_командлета> -detailed Пример: get-help use-transaction -detailed ЭЛЕМЕНТЫ, ПОДДЕРЖИВАЮЩИЕ ТРАНЗАКЦИИ Для участия в транзакции и командлет, и поставщик должны поддерживать транзакции. Эта функция встроена в объекты, на которые влияет транзакция. Поставщик Windows PowerShell Registry поддерживает транзакции в Windows Vista. Объект TransactedString (Microsoft.PowerShell.Commands.Management.TransactedString) работает в любой операционной системе, где установлена оболочка Windows PowerShell. Другие поставщики Windows PowerShell могут поддерживать транзакции. Узнать, какие поставщики Windows PowerShell в текущем сеансе поддерживают транзакции, можно с помощью следующей команды, возвращающей значение "Transactions" свойства поставщиков Capabilities: get-psprovider | where {$_.Capabilities -like "*transactions*"} Дополнительные сведения о поставщиках см. в справке об этих поставщиках. Для получения справки по поставщику введите следующую команду: get-help <имя-поставщика> Например, чтобы получить справку для поставщика 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 в каждый момент времени активна только одна транзакция и управлять можно только одной активной транзакцией. В один сеанс одновременно может выполняться несколько транзакций, но активна только транзакция, запущенная последней. Поэтому при использовании командлетов транзакций нельзя выбирать определенные транзакции. Команды всегда применяются к активной транзакции. Это хорошо иллюстрирует поведение командлета Get-Transaction. Команда Get-Transaction при вводе всегда возвращает только один объект транзакции. Этот объект представляет активную транзакцию. Для управления другой транзакцией нужно сначала закончить активную транзакцию, зафиксировав или откатив ее. После этого предыдущая транзакция автоматически становится активной. Транзакции становятся активным в порядке, обратном запуску, то есть транзакция, запущенная последней, всегда активна. ПОДПИСЧИКИ И НЕЗАВИСИМЫЕ ТРАНЗАКЦИИ При запуске транзакции во время выполнения другой транзакции Windows PowerShell по умолчанию не запускает новую транзакцию. Вместо этого в текущую транзакцию добавляется "подписчик". Если у транзакции несколько подписчиков, одна команда Undo-Transaction в любой момент откатывает всю транзакцию для всех подписчиков. При этом для фиксации транзакции необходимо ввести по одной команде Complete-Transaction для каждого подписчика. Чтобы узнать количество подписчиков в транзакции, проверьте свойство SubscriberCount объекта транзакции. Например, следующая команда использует командлет Get-Transaction, чтобы вернуть значение свойства SubscriberCount активной транзакции: (Get-Transaction).SubscriberCount Добавление подписчика - поведение по умолчанию, потому что большинство транзакций, запускаемых при выполнении другой транзакции, связаны с этой исходной транзакцией. В обычной ситуации скрипт, содержащий транзакцию, вызывает вспомогательный скрипт, содержащий собственную транзакцию. Эти транзакции связаны, поэтому их нужно откатывать или фиксировать единым блоком. Однако с помощью параметра Independent командлета Start-Transaction можно запустить транзакцию, независимую от текущей. При запуске независимой транзакции командлет Start-Transaction создает новый объект транзакции и новая транзакция становится активной. Независимую транзакцию можно зафиксировать или откатить, не затрагивая первоначальную транзакцию. По завершении (фиксации или отката) независимой транзакции первоначальная транзакция снова становится активной. ИЗМЕНЕНИЕ ДАННЫХ При использовании транзакций для изменения данных данные, на которые влияет транзакция, не изменяются до фиксации транзакции. Однако те же данные можно изменять с помощью команд, не входящих в транзакцию. Об этом следует помнить при использовании транзакций для управления общими данными. Обычно у баз данных есть механизмы, блокирующие данные при работе с ними, чтобы их не могли изменить другие пользователи, команды, скрипты и функции. Однако блокирование обеспечивается базой данных. Оно не связано с транзакциями. При работе в файловой системе или другом хранилище данных, поддерживающем транзакции, данные могут изменяться во время выполнения транзакции. ПРИМЕРЫ Примеры в данном разделе используют поставщик Windows PowerShell Registry, поэтому предполагается, что вы с ним знакомы. Чтобы получить сведения о поставщике Registry, введите команду "get-help registry". ПРИМЕР 1: ФИКСАЦИЯ ТРАНЗАКЦИИ Чтобы создать транзакцию, используйте командлет Start-Transaction. Следующая команда запускает транзакцию с параметрами по умолчанию. start-transaction Для включения в транзакцию команд используется параметр командлета UseTransaction. По умолчанию команды не включаются в транзакцию. Например, следующая команда, назначающая текущим расположением раздел Software на диске HKCU:, не включена в транзакцию. cd hkcu:\Software Следующая команда, создающая раздел MyCompany, использует параметр UseTransaction командлета New-Item, чтобы включить команду в активную транзакцию. 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, использует параметр UseTransaction командлета New-Item, чтобы включить команду в активную транзакцию. 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, чтобы добавить в раздел MyCompany запись реестра MyKey. Команда использует параметр UseTransaction для включения команды в транзакцию. new-itemproperty -path MyCompany -Name MyKey -value 123 -UseTransaction Команда возвращает объект, представляющий новую запись реестра, но не изменяет саму запись реестра. MyKey ----- 123 Для получения текущих элементов в реестре используйте команду Get-ChildItem ("dir") без параметра UseTransaction. Следующая команда возвращает элементы, начинающиеся на "M". dir m* В результатах показано, что в раздел MyCompany записи еще не добавлены. Hive: HKEY_CURRENT_USER\Software SKC VC Name Property --- -- ---- -------- 83 1 Microsoft {(default)} 0 0 MyCompany {} Чтобы узнать, как будет выглядеть эффект от фиксации транзакции, введите команду Get-ChildItem ("dir") с параметром UseTransaction. Эта команда содержит представление данных из транзакции. dir m* -useTransaction В результатах показано, что при фиксации транзакции в раздел MyCompany будет добавлена запись MyKey. Hive: HKEY_CURRENT_USER\Software SKC VC Name Property --- -- ---- -------- 83 1 Microsoft {(default)} 0 1 MyCompany {MyKey} ПРИМЕР 4: ОБЪЕДИНЕНИЕ КОМАНД В РАМКАХ ТРАНЗАКЦИЙ И ВНЕ ТРАНЗАКЦИЙ Во время транзакции можно вводить команды, не входящие в транзакцию. Команды, не входящие в транзакцию, влияют на данные немедленно, но не влияют на транзакцию. Следующая команда запускает транзакцию в разделе реестра HKCU:\Software. start-transaction Три следующие команды добавляют в реестр разделы с помощью командлета New-Item. Первая и третья команды включаются в транзакцию с помощью параметра UseTransaction. Во второй команде этот параметр опускается. Поскольку вторая команда не входит в транзакцию, она действует немедленно. new-item MyCompany1 -UseTransaction new-item MyCompany2 new-item MyCompany3 -UseTransaction Для просмотра текущего состояния реестра используйте команду Get-ChildItem ("dir") без параметра UseTransaction. Эта команда возвращает элементы, начинающиеся на "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 : раздел по этому пути уже существует В строке:1 знак:9 + new-item <<<< MyCompany -usetx Команда Get-Transaction подтверждает, что выполнен откат транзакции и что количество подписчиков равно 0. RollbackPreference: SubscriberCount: Status ------------------ --------------- ------ Error 0 RolledBack ПРИМЕР 6: ИЗМЕНЕНИЕ ПАРАМЕТРА ОТКАТА Если нужно, чтобы транзакция была менее чувствительна к ошибкам, можно использовать параметр RollbackPreference командлета Start-Transaction, чтобы изменить параметр отката. Следующая команда запускает транзакцию с параметром отката "Never". start-transaction -rollbackpreference Never В этом случае при ошибке команды транзакция не откатывается автоматически. New-Item MyCompany -UseTX New-Item : раздел по этому пути уже существует В строке:1 знак:9 + new-item <<<< MyCompany -usetx Так как транзакция еще активна, команду можно повторно ввести как часть транзакции. New-Item MyOtherCompany -UseTX ПРИМЕР 7: ИСПОЛЬЗОВАНИЕ КОМАНДЛЕТА USE-TRANSACTION Командлет Use-Transaction позволяет непосредственно выполнять скрипты над поддерживающими транзакции объектами 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 Следующая команда с помощью метода Append объекта TransactedString добавляет текст к строке. Поскольку команда не является частью транзакции, изменение вступает в силу немедленно. $t.append("Windows") Следующая команда использует для добавления текста тот же метод Append, но добавляет текст как часть транзакции. Команда заключена в фигурные скобки и устанавливается как значение параметра ScriptBlock командлета Use-Transaction. Параметр UseTransaction (UseTx) является обязательным. use-transaction {$t.append(" PowerShell")} -usetx Для просмотра текущего содержимого в $t строки, над которой выполняется транзакция, используйте метод ToString объекта TransactedString. $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, чтобы добавить в раздел MyCompany запись реестра MyKey. Она использует параметр 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. Чтобы зафиксировать транзакцию с несколькими подписчиками, необходимо ввести по одной команде Complete-Transaction для каждой команды Start-Transaction. complete-transaction Еще одна команда Get-Transaction показывает, что транзакция зафиксирована. RollbackPreference: SubscriberCount: Status ------------------ --------------- ------ Error 0 Committed ПРИМЕР 8: УПРАВЛЕНИЕ НЕЗАВИСИМЫМИ ТРАНЗАКЦИЯМИ При запуске транзакции во время выполнения другой транзакции можно использовать параметр Independent командлета Start-Transaction, чтобы новая транзакция была независима от первоначальной. При этом командлет 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 Обратите внимание, что количество подписчиков транзакции равно 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