Обработка операций фиксации
Существует два типа операций фиксации: однофазная фиксация и многофазная фиксация. Одноэтапная операция фиксации состоит из одного уведомления, на которое должны отвечать диспетчеры ресурсов, а многофазная операция фиксации включает дополнительные уведомления о шагах подготовки.
Однофазную операцию фиксации проще реализовать. Он подходит для систем обработки транзакций (TPS), которые имеют одну из следующих характеристик:
Один диспетчер ресурсов.
Несколько диспетчеров ресурсов, все из которых, кроме одного, доступны только для чтения и не участвуют в операции фиксации.
Если в операции фиксации участвуют несколько диспетчеров ресурсов, требуется многоэтапная операция фиксации.
Операции фиксации Single-Phase
Если вы хотите, чтобы ваш TPS поддерживал однофазные операции фиксации, один (и только один) диспетчер ресурсов должен зарегистрироваться для получения TRANSACTION_NOTIFY_SINGLE_PHASE_COMMIT уведомлений о зачислении. Все остальные диспетчеры ресурсов должны быть доступны только для чтения.
TPS, включающая диспетчер транзакций высокого приоритета , не может использовать однофазную фиксацию.
Если диспетчер ресурсов зарегистрирован для получения TRANSACTION_NOTIFY_SINGLE_PHASE_COMMIT уведомлений, KTM отправляет такое уведомление, когда транзакционный клиент вызывает ZwCommitTransaction.
Когда диспетчер ресурсов получает уведомление TRANSACTION_NOTIFY_SINGLE_PHASE_COMMIT для транзакции, он может либо зафиксировать транзакцию, либо отклонить однофазную фиксацию.
Чтобы зафиксировать транзакцию, диспетчер ресурсов должен выполнить следующие действия:
Сбросите все данные, которые он содержит в непостоянных кэшах (хранилище в памяти), например область маршалинга CLFS для потока журналов CLFS.
Диспетчер ресурсов должен переместить данные из кэша в устойчивое хранилище. Например, диспетчер ресурсов, использующий CLFS, может вызывать ClfsFlushBuffers.
Сделайте все изменения данных постоянными и общедоступными (то есть видимыми за пределами область диспетчера ресурсов).
Вызовите ZwCommitComplete.
После вызова ZwCommitComplete диспетчер ресурсов должен вызвать ZwClose , чтобы закрыть дескриптор зачисления.
Чтобы отклонить однофазную операцию фиксации для транзакции, диспетчер ресурсов может вызвать ZwSinglePhaseReject. Если диспетчер ресурсов вызывает ZwSinglePhaseReject, KTM немедленно изменяет операцию фиксации с однофазной на многофазную.
Если другие диспетчеры ресурсов завербовываются в той же транзакции, они должны быть доступны только для чтения. Однако они должны зарегистрироваться для получения уведомления о TRANSACTION_NOTIFY_RM_DISCONNECTED, которое они получают, если диспетчер ресурсов, обрабатывающий однофазную операцию фиксации, закрывает дескриптор зачисления, не указывая на фиксацию или откат транзакции.
Многофазные операции фиксации
Многофазная операция фиксации начинается, когда происходит одно из следующих событий:
Транзакционный клиент вызывает ZwCommitTransaction, и диспетчеры ресурсов не зарегистрировались для получения TRANSACTION_NOTIFY_SINGLE_PHASE_COMMIT уведомлений.
Диспетчер ресурсов вызывает ZwSinglePhaseReject после получения уведомления TRANSACTION_NOTIFY_SINGLE_PHASE_COMMIT.
Улучшенный диспетчер транзакций вызывает ZwPrePrepareEnlistment.
Многофазные операции фиксации состоят из трех последовательных этапов: предварительная подготовка, подготовка и фиксация.
Этап предварительной подготовки
Этап предварительной подготовки (также называемый нулевым этапом) операции фиксации начинается, когда KTM отправляет уведомление TRANSACTION_NOTIFY_PREPREPARE всем диспетчерам ресурсов. KTM отправляет это уведомление, если ни один из диспетчеров ресурсов не поддерживает однофазную операцию фиксации для транзакции или если улучшенный диспетчер транзакций вызывает ZwPreprepareEnlistment.
Когда каждый диспетчер ресурсов получает уведомление TRANSACTION_NOTIFY_PREPREPARE, он должен сделать следующее:
Сбросите все данные, которые он содержит в непостоянных кэшах (хранилище в памяти), например область маршалинга CLFS для потока журналов CLFS.
Диспетчер ресурсов должен переместить данные из кэша в устойчивое хранилище. Например, диспетчер ресурсов, использующий CLFS, может вызывать ClfsFlushBuffers.
Вызовите ZwPrePrepareComplete.
После того как диспетчер ресурсов вызовет ZwPreprepareComplete, он может продолжать получать и обслуживать клиентские запросы. Однако диспетчер ресурсов должен рассматривать все изменения данных как операции сквозной передачи кэша, которые немедленно записываются в устойчивый носитель хранилища.
Если диспетчер ресурсов обнаруживает ошибку при обработке уведомления TRANSACTION_NOTIFY_PREPREPARE, он должен вызвать ZwRollbackEnlistment для отката транзакции.
Этап подготовки
Этап подготовки (также называемый этапом 1) операции фиксации начинается, когда KTM отправляет уведомление TRANSACTION_NOTIFY_PREPARE всем диспетчерам ресурсов. KTM отправляет это уведомление после TRANSACTION_NOTIFY_PREPREPARE, если диспетчеры ресурсов не поддерживают однофазную фиксацию или если более высокий диспетчер транзакций вызывает ZwPrepareEnlistment.
Когда каждый диспетчер ресурсов получает уведомление TRANSACTION_NOTIFY_PREPARE, он должен сделать следующее:
Остановите обслуживание клиентских запросов и сообщите обо всех последующих запросах клиента как об ошибках клиента.
Убедитесь, что все данные перемещены в устойчивое хранилище.
Вызовите ZwPrepareComplete.
Если диспетчер ресурсов обнаруживает ошибку при обработке уведомления TRANSACTION_NOTIFY_PREPARE, он должен вызвать ZwRollbackEnlistment для отката транзакции. Однако диспетчер ресурсов не может выполнить откат транзакции после вызова ZwPrepareComplete.
Этап фиксации
Этап фиксации (также известный как второй этап) операции фиксации начинается, когда KTM отправляет уведомление TRANSACTION_NOTIFY_COMMIT всем диспетчерам ресурсов. KTM отправляет это уведомление после TRANSACTION_NOTIFY_PREPARE, если ни один из диспетчеров ресурсов не поддерживает однофазную фиксацию или если более высокий диспетчер транзакций вызывает ZwCommitEnlistment.
Когда каждый диспетчер ресурсов получает уведомление TRANSACTION_NOTIFY_COMMIT, он должен сделать следующее:
Сделайте все изменения данных постоянными и общедоступными (то есть видимыми для других транзакций).
Как правило, диспетчер ресурсов делает изменения постоянными и общедоступными, копируя сохраненные данные транзакции из потока журналов в общедоступное постоянное хранилище базы данных. Дополнительные сведения об использовании потоков журналов см. в статье Использование потоков журналов с KTM.
Вызовите ZwCommitComplete.
После вызова ZwCommitComplete диспетчер ресурсов должен вызвать ZwClose , чтобы закрыть дескриптор зачисления.
Если диспетчер ресурсов обнаруживает ошибку при обработке уведомления TRANSACTION_NOTIFY_COMMIT, он должен завершить работу. В следующий раз, когда операционная система перезагрузит диспетчер ресурсов, процесс восстановления диспетчера ресурсов должен восстановить транзакцию до состояния, которое было известно как работоспособное до возникновения ошибки.