Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Любая система обработки транзакций (TPS), использующая диспетчер транзакций ядра (KTM) и общую файловую систему журнала (CLFS), должна содержать следующие важные компоненты:
Диспетчер транзакций (KTM)
KTM отслеживает состояние каждой транзакции и координирует операции восстановления после сбоя системы.
Один или несколько диспетчеров ресурсов
Диспетчеры ресурсов, которые предоставляются вами, управляют данными, связанными с каждой транзакцией.
Один или несколько CLFS потоков журналов
Диспетчер транзакций и диспетчеры ресурсов используют потоки журналов CLFS для записи сведений, которые можно использовать для фиксации, отката или восстановления транзакции.
Один или несколько транзакционных клиентов
Как правило, каждый транзакционный клиент TPS может создать транзакцию, выполнять операции с данными в контексте транзакции, а затем инициировать операцию фиксации или отката для транзакции.
В этом разделе описывается простой TPS с одним диспетчером ресурсов, более сложным TPS, который содержит несколько диспетчеров ресурсов и некоторые другие сценарии TPS.
В разделе "Использование KTM " содержатся подробные сведения об использовании KTM для создания компонентов TPS.
Простые TPS
Простой TPS может состоять из KTM, одного диспетчера ресурсов и CLFS. Клиенты транзакций могут взаимодействовать с диспетчером ресурсов через интерфейс, предоставляемый диспетчером ресурсов.
Например, предположим, что вы хотите создать систему управления базами данных. Вы хотите, чтобы клиенты вашей системы получили доступ к базе данных, открыв дескриптор к объекту базы данных, выполняя операции чтения и записи с объектом, а затем закрывая дескриптор объекта.
Теперь предположим, что необходимо, чтобы наборы операций чтения и записи происходили атомарно, чтобы другие пользователи системы видели только окончательный результат. Эту цель можно достичь, создав TPS, которая позволяет клиентам привязать наборы операций базы данных к транзакции.
Система должна включать диспетчер ресурсов, который управляет данными в базе данных в ответ на запросы клиентов на чтение и запись. Этот диспетчер ресурсов может экспортировать интерфейс программирования приложения (API), который позволяет клиентам связывать транзакцию с набором операций чтения и записи.
При загрузке диспетчера ресурсов он должен зарегистрировать себя в KTM, вызвав ZwCreateTransactionManager и ZwCreateResourceManager. Затем диспетчер ресурсов может участвовать в транзакциях.
Возможно, диспетчер ресурсов поддерживает набор функций, позволяющих клиентам создавать объекты данных, читать и записывать данные, связанные с объектами данных, и закрывать объекты данных. В следующем псевдокоде показан пример последовательности кода клиента.
CreateDataObject (IN TransactionID, OUT DataHandle);
ReadData (IN DataHandle, OUT Data);
WriteData (IN DataHandle, IN Data);
WriteData (IN DataHandle, IN Data);
WriteData (IN DataHandle, IN Data);
CloseDataObject (IN DataHandle);
Прежде чем клиент сможет вызвать подпрограмму CreateDataObject диспетчера ресурсов, клиент должен создать объект транзакции путем вызова подпрограммы ZwCreateTransaction KTM и получения идентификатора объекта транзакции путем вызова ZwQueryInformationTransaction.
Когда клиент вызывает подпрограмму CreateDataObject диспетчера ресурсов, клиент передает идентификатор объекта транзакции в диспетчер ресурсов. Диспетчер ресурсов может вызвать ZwOpenTransaction , чтобы получить дескриптор объекта транзакции, а затем вызвать ZwCreateEnlistment , чтобы зарегистрировать его участие в транзакции.
На этом этапе клиент может начать выполнять операции с объектом данных. Так как клиент предоставил идентификатор транзакции при создании объекта данных, диспетчер ресурсов может назначать все операции чтения и записи для транзакции.
Диспетчер ресурсов должен записывать все результаты операций с данными, которые клиент указывает, не делая результаты постоянными. Как правило, диспетчер ресурсов использует CLFS для записи операций в потоке журнала транзакций.
Когда клиент завершит вызов диспетчера ресурсов для выполнения транзакционных операций, он вызывает подпрограмму ZwCommitTransaction KTM. На этом этапе KTM уведомляет менеджера ресурсов, что операции должны стать постоянными. Затем диспетчер ресурсов перемещает результаты операции из потока журналов в постоянный носитель хранилища данных. Наконец, менеджер ресурсов вызывает ZwCommitComplete, чтобы сообщить KTM, что операция фиксации завершена.
Что произойдет, если диспетчер ресурсов сообщает об ошибке для одного из вызовов клиента ReadData или WriteData? Клиент может вызвать ZwRollbackTransaction для отката транзакции. В результате этого вызова KTM уведомляет диспетчера ресурсов о том, что он должен восстановить данные до их первоначального состояния. Затем клиент может создать новую транзакцию для тех же операций или не продолжить.
В следующем псевдокоде показан пример более подробной последовательности транзакционных операций клиента.
ZwCreateTransaction (&TransactionHandle, ...);
ZwQueryInformationTransaction (TransactionHandle, ...);
CreateDataObject (TransactionID, &DataHandle);
Status = ReadData (DataHandle, &Data1);
if (Status == Error) goto ErrorRollback;
Status = WriteData (DataHandle, Data2);
if (Status == Error) goto ErrorRollback;
Status = WriteData (DataHandle, Data3);
if (Status == Error) goto ErrorRollback;
Status = WriteData (DataHandle, Data4);
if (Status == Error) goto ErrorRollback;
ZwCommitTransaction (TransactionHandle, ...);
goto Leave;
ErrorRollback:
ZwRollbackTransaction (TransactionHandle, ...);
Leave:
ZwClose (TransactionHandle);
return;
Что произойдет, если система дает сбой после создания транзакции, но до ее фиксации или отката? Каждый раз, когда диспетчер ресурсов загружает, он должен вызывать ZwRecoverTransactionManager и ZwRecoverResourceManager. Вызов ZwRecoverTransactionManager приводит к тому, что KTM открывает поток журнала и считывает историю транзакций. Вызов ZwRecoverResourceManager приводит к тому, что KTM уведомляет диспетчер ресурсов о любых учтённых транзакциях, которые выполнялись до сбоя, и какие из них должен восстановить диспетчер ресурсов.
Если транзакционный клиент вызвал ZwCommitTransaction для транзакции перед сбоем и начал обработку операций фиксации для этой транзакции, диспетчер ресурсов должен иметь возможность восстановить состояние транзакции до момента непосредственно перед сбоем. Если клиент не был готов зафиксировать транзакцию до сбоя, диспетчер ресурсов может удалить данные и откатить транзакцию.
Дополнительные сведения о том, как писать транзакционные клиенты, см. в статье Создание транзакционного клиента.
Дополнительные сведения о создании диспетчеров ресурсов см. в статье "Создание диспетчера ресурсов".
Несколько менеджеров ресурсов в TPS
Теперь предположим, что TPS позволяет клиентам изменять сведения в двух отдельных базах данных в рамках одной транзакции, чтобы транзакция была успешной, только если изменения обеих баз данных успешно выполнены.
В этом случае TPS может иметь два диспетчера ресурсов, по одному для каждой базы данных. Каждый диспетчер ресурсов может экспортировать API, который клиенты могут использовать для доступа к базе данных диспетчера ресурсов.
В следующем псевдокоде показано, как клиент может создать одну транзакцию, содержащую операции с двумя базами данных, которые поддерживают два диспетчера ресурсов.
В этом примере клиент считывает данные из первой базы данных и записывает его во вторую базу данных. Затем клиент считывает данные из второй базы данных и записывает его в первую базу данных. (Первый диспетчер ресурсов экспортирует функции, начинающиеся с Rm1, а второй диспетчер ресурсов экспортирует функции, начинающиеся с Rm2.)
ZwCreateTransaction (&TransactionHandle, ...);
ZwQueryInformationTransaction (TransactionHandle, ...);
Rm1CreateDataObject (TransactionID, &Rm1DataHandle);
Rm2CreateDataObject (TransactionID, &Rm2DataHandle);
Status = Rm1ReadData (Rm1DataHandle, &Rm1Data);
if (Status == Error) goto ErrorRollback;
Status = Rm2WriteData (Rm2DataHandle, Rm1Data);
if (Status == Error) goto ErrorRollback;
Status = Rm2ReadData (Rm2DataHandle, &Rm2Data);
if (Status == Error) goto ErrorRollback;
Status = Rm1WriteData (Rm1DataHandle, Rm2Data);
if (Status == Error) goto ErrorRollback;
ZwCommitTransaction (TransactionHandle, ...);
goto Leave;
ErrorRollback:
ZwRollbackTransaction (TransactionHandle, ...);
Leave:
ZwClose (TransactionHandle);
return;
Так как клиент передает один и тот же идентификатор транзакции обоим диспетчерам ресурсов, оба диспетчера ресурсов могут вызывать ZwOpenTransaction и ZwCreateEnlistment для включения в транзакцию. Когда клиент в конечном итоге вызывает ZwCommitTransaction, KTM уведомляет каждого диспетчера ресурсов о том, что менеджер должен сделать операции постоянными, и каждый диспетчер ресурсов вызывает ZwCommitComplete после завершения.
Другие сценарии TPS
KTM поддерживает другие сценарии TPS. Например, в следующих сценариях описываются компоненты, которые может содержать TPS:
Один диспетчер ресурсов, который управляет несколькими базами данных.
API диспетчера ресурсов может позволить клиентам открывать и получать доступ к нескольким базам данных одновременно, а клиент может объединять доступ к нескольким базам данных в одной транзакции.
Один диспетчер ресурсов с API, который клиенты вызывают, и дополнительные диспетчеры ресурсов с API, которые вызывает первый диспетчер ресурсов.
Клиент взаимодействует только с первым диспетчером ресурсов. Когда этот диспетчер ресурсов обрабатывает запросы от клиента, он может получить доступ к дополнительным диспетчерам ресурсов по мере необходимости для обработки запросов клиента. Например, диспетчер ресурсов управляет клиентской базой данных, требующей операций резервного копирования или проверки данных из второго диспетчера ресурсов, недоступного клиентам.
Существующий клиент и диспетчер ресурсов, которые не используют KTM, интегрированы с дополнительным набором диспетчеров ресурсов, использующих KTM.
В этом случае обычно необходимо изменить существующий диспетчер ресурсов, чтобы он стал превосходным диспетчером транзакций , который взаимодействует с KTM.