Поделиться через


Обработка восстановления

После любого типа сбоя, который нарушает нормальную обработку транзакций, KTM и каждый диспетчер ресурсов должны выполнять операции восстановления . Восстановление — это процесс, с помощью которого участники транзакции приходят к согласованному представлению состояния каждой транзакции.

Руководители ресурсов могут сомневаться в результатах транзакции, а это означает, что во время сбоя они получили TRANSACTION_NOTIFY_PREPARE уведомление, подготовились к долговременному хранилищу, но не получили (или не получили, но не зарегистрировали) окончательный результат транзакции. Аналогичным образом, KTM может сомневаться в транзакции, если она была подготовлена, но не получила (или не получила, но не зарегистрировала) результат. Во время восстановления необходимо повторно отправить все результаты, которые были отправлены, но не подтверждены. Например, если диспетчер ресурсов получил уведомление TRANSACTION_NOTIFY_COMMIT и вызвал функцию CommitComplete , RM может по-прежнему получать повторяющееся уведомление TRANSACTION_NOTIFY_COMMIT во время восстановления.

Чтобы транзакция правильно восстанавливалась после сбоя диспетчера ресурсов или системы, каждый диспетчер ресурсов должен выполнять следующие действия при каждом запуске:

  1. Вызовите функцию OpenResourceManager , чтобы повторно открыть дескриптор resource manager, используя его уникальное постоянное имя. Это сообщает KTM о том, что диспетчер ресурсов снова запущен и доступен для выполнения восстановления. Если не существует заверений для восстановления, вызов OpenResourceManager может завершиться ошибкой. Вызовите CreateResourceManager , чтобы повторно создать объект RM.

  2. Вызовите RecoverResourceManager. Диспетчер ресурсов получит событие уведомления TRANSACTION_NOTIFY_RECOVER для каждого зачисления, для которого необходимо выполнить операции восстановления, а затем TRANSACTION_NOTIFY_LAST_RECOVER. Событие уведомления содержит глобальный уникальный идентификатор как для транзакции, так и для зачисления.

  3. Вызовите функцию OpenEnlistment , чтобы повторно открыть каждый дескриптор зачисления, для которого диспетчер ресурсов получил уведомление TRANSACTION_NOTIFY_RECOVER.

  4. Для каждого зачисления, открытого OpenEnlistment, вызовите RecoverEnlistment. Это приводит к повторной отправке уведомления о TRANSACTION_NOTIFY_COMMIT или TRANSACTION_NOTIFY_INDOUBT.

  5. Если RM получил TRANSACTION_NOTIFY_COMMIT, RM может завершить транзакцию, вызвав CommitComplete.

    Если RM получил TRANSACTION_NOTIFY_INDOUBT, RM должен дождаться получения уведомления о результатах.

  6. Для любых транзакций, для которые RM не получает уведомление TRANSACTION_NOTIFY_RECOVER, но ранее получил уведомление TRANSACTION_NOTIFY_PREPARE, RM должен обрабатывать транзакцию так, как если бы она была откатна.

Примечание

Диспетчеры ресурсов могут заверять или создавать новые транзакции в процессе восстановления.

 

KTM использует предполагаемую модель транзакций прерывания . Это поведение иллюстрируется в следующем сценарии. Предположим, что KTM и resource manager существуют на одном компьютере. Предположим, KTM выдает уведомление о подготовке транзакции, но система завершает работу, прежде чем KTM регистрирует уведомление о подготовке. Далее предположим, что диспетчер ресурсов получает и регистрирует уведомление о подготовке непосредственно перед сбоем системы. После восстановления системы KTM не имеет сведений о транзакции, так как она никогда не регистрировала этап подготовки. Диспетчер ресурсов знает о транзакции, так как он получил, обработал и зарегистрировал уведомление о подготовке. Когда KTM выдает уведомления о восстановлении, диспетчер ресурсов не включает уведомление о восстановлении для рассматриваемой транзакции. При использовании модели предполагаемого прерывания диспетчер ресурсов в этом случае будет рассматривать подготовленную транзакцию как прерванную, если он не получает уведомлений о выполнении восстановления для этой транзакции.