Criando um Resource Manager
Os gerenciadores de recursos mantêm os dados de cada transação e registram as operações da transação. Se um TPS (sistema de processamento de transações) tiver vários gerenciadores de recursos, cada gerenciador de recursos poderá participar das operações de confirmação, reversão e recuperação de cada transação.
Cada gerenciador de recursos deve exportar uma interface que os clientes transacionais podem usar para acessar o banco de dados ou outro recurso que o gerenciador de recursos mantém.
Normalmente, um gerenciador de recursos no modo kernel deve executar as seguintes tarefas na ordem listada:
Criar um fluxo de log.
Os gerenciadores de recursos podem usar o CLFS ( Common Log File System ) ou algum outro recurso de registro em log para manter seus fluxos de log. Uma chamada para ClfsCreateLogFile cria um fluxo de log CLFS. O gerenciador de recursos deve usar o fluxo de log para registrar todas as informações necessárias para confirmar, reverter ou recuperar transações. Além disso, o KTM usa o fluxo de log para registrar quaisquer alterações de estado internas que possam ser necessárias para recuperar transações.
Crie um objeto do gerenciador de transações.
Uma chamada para ZwCreateTransactionManager cria um objeto do gerenciador de transações e conecta o gerenciador de recursos a um fluxo de log CLFS adicional especificado pelo gerenciador de recursos.
Recuperar o estado do gerenciador de transações.
Uma chamada para ZwRecoverTransactionManager lê o fluxo de log do objeto do gerenciador de transações (que o KTM mantém) e determina se o TPS foi desligado antes de todas as transações serem concluídas (por exemplo, porque o sistema falhou). A KTM restaura seu estado interno com base nas informações no fluxo de log.
Criar um objeto do gerenciador de recursos.
Uma chamada para ZwCreateResourceManager cria um objeto do gerenciador de recursos e o associa ao objeto gerenciador de transações criado anteriormente.
Recuperar o estado do gerenciador de recursos.
Uma chamada para ZwRecoverResourceManager faz com que a KTM envie o gerenciador de recursos TRANSACTION_NOTIFY_RECOVER notificações para todas as transações que estavam em andamento na última vez que o gerenciador de recursos foi desligado. Para obter informações sobre como o gerenciador de recursos deve responder a essas notificações, consulte Manipulando operações de recuperação.
Receber transações de clientes.
Normalmente, um cliente cria um objeto de transação e usa a interface do cliente do gerenciador de recursos para passar o GUID do objeto de transação para o gerenciador de recursos. Por exemplo, o gerenciador de recursos pode fornecer uma rotina CreateDataObject semelhante à que o tópico Noções básicas sobre componentes TPS descreve.
Inscreva-se em cada transação.
Uma chamada para ZwOpenTransaction abre um identificador para o objeto de transação e, em seguida, uma chamada para ZwCreateEnlistment cria uma inscrição para a transação. A inscrição permite que o gerenciador de recursos receba um conjunto especificado de notificações de transação.
Habilitar a recepção de notificações de transação.
O gerenciador de recursos pode chamar ZwGetNotificationResourceManager para obter notificações de forma síncrona ou pode chamar TmEnableCallbacks para registrar uma rotina de retorno de chamada ResourceManagerNotification que a KTM chama sempre que uma notificação estiver disponível.
Solicitações de acesso a recursos de serviço de clientes, mas não tornam as alterações permanentes.
Depois que um cliente cria um objeto de transação, ele normalmente chama a interface do gerenciador de recursos para acessar o recurso do gerenciador de recursos. Por exemplo, um gerenciador de recursos de um banco de dados pode receber solicitações para ler e gravar no banco de dados.
O gerenciador de recursos deve registrar os resultados das operações de leitura e gravação em um fluxo de log CLFS ou em outro recurso de log até receber uma notificação de que as operações da transação serão confirmadas, revertidas ou recuperadas.
Confirmar ou reverter operações de cliente.
Eventualmente, o gerenciador de recursos recebe uma notificação para começar a confirmar ou reverter as operações que o cliente executou. Em resposta, o gerenciador de recursos deve tornar as operações de cliente permanentes ou descartá-las. Para obter mais informações sobre como lidar com notificações de confirmação e reversão, consulte Manipulando operações de transação.
Ocasionalmente, um gerenciador de recursos pode ter que tentar forçar a KTM a fornecer rapidamente uma notificação de confirmação ou reversão, talvez porque o gerenciador de recursos determinou que um dispositivo foi removido de surpresa. Nesse caso, o gerenciador de recursos pode chamar TmRequestOutcomeEnlistment.
Feche o identificador do objeto de inscrição.
Depois que o gerenciador de recursos terminar de processar a transação, ele deverá chamar ZwClose para fechar o identificador do objeto de inscrição
Feche o identificador de objeto do gerenciador de recursos e o identificador de objeto do gerenciador de transações.
Antes que o gerenciador de recursos descarregue, ele deve chamar ZwClose para fechar o identificador do objeto do gerenciador de recursos e o identificador do objeto do gerenciador de transações.
As etapas 1 a 5 devem ser executadas no código de inicialização do gerenciador de recursos. Por exemplo, se o gerenciador de recursos for um driver no modo kernel, o código de inicialização será a rotina driverEntry do driver.
As etapas 6 a 11 normalmente são executadas em código que responde a solicitações de clientes transacionais.
A etapa 12 deve ser executada no código final de limpo do gerenciador de recursos, como a rotina de descarregamento de um driver no modo kernel.
Criando uma inscrição Read-Only
Um alistamento somente leitura é um alistamento que não recebe nenhuma notificação da KTM. Um gerenciador de recursos pode fazer qualquer inscrição somente leitura chamando ZwReadOnlyEnlistment. Essa chamada faz com que o KTM pare de fornecer notificações ao gerenciador de recursos.
Depois que o gerenciador de recursos chamar ZwCreateEnlistment, ele poderá chamar ZwReadOnlyEnlistment a qualquer momento até o ponto em que normalmente chamaria ZwPrepareComplete.
Há dois motivos pelos quais você pode querer que seu gerenciador de recursos chame ZwReadOnlyEnlistment.
Seu gerenciador de recursos tem participado de uma transação e, em algum momento antes de receber uma notificação TRANSACTION_NOTIFY_COMMIT, o gerenciador de recursos determina que ele não precisa mais participar da operação de confirmação da transação.
Por exemplo, quando o gerenciador de recursos recebe uma notificação TRANSACTION_NOTIFY_PREPARE, ele pode determinar que nenhuma das operações da transação alterou o banco de dados do gerenciador de recursos. O gerenciador de recursos pode chamar ZwReadOnlyEnlistment em vez de ZwPrepareComplete para se remover da transação.
O gerenciador de recursos nunca participa da operação de confirmação de nenhuma transação.
Por exemplo, o gerenciador de recursos pode monitorar os dados que o cliente envia, sem modificar nenhum banco de dados armazenado. Nesse caso, o gerenciador de recursos pode chamar ZwReadOnlyEnlistment imediatamente depois de chamar ZwCreateEnlistment. Além disso, você pode optar por tornar esse gerenciador de recursos volátil, conforme descrito na próxima seção deste tópico.
Depois que um gerenciador de recursos tiver chamado ZwReadOnlyEnlistment, ele poderá chamar ZwClose para fechar o identificador de inscrição.
Criando um gerenciador de Volatile-Resource
Um gerenciador de recursos voláteis é um gerenciador de recursos que não mantém dados duráveis. Por exemplo, você pode criar um gerenciador de recursos voláteis para monitorar os dados que o cliente envia, se o gerenciador de recursos não modificar um banco de dados armazenado de maneira durável. Os gerenciadores de recursos voláteis normalmente não registram a atividade de transação e, portanto, não podem executar operações de recuperação ou reversão.
Um gerenciador de recursos voláteis deve definir o sinalizador RESOURCE_MANAGER_VOLATILE quando chamar ZwCreateResourceManager. Se esse sinalizador estiver definido, o KTM não registrará nenhuma informação sobre o gerenciador de recursos no fluxo de log do objeto do gerenciador de transações associado.
O gerenciador de recursos também pode definir um sinalizador de TRANSACTION_MANAGER_VOLATILE quando chama ZwCreateTransactionManager. Se esse sinalizador estiver definido, o KTM não criará um fluxo de log para o objeto do gerenciador de transações. Além disso, todos os gerenciadores de recursos adicionais conectados ao objeto do gerenciador de transações também devem ser voláteis e definir o sinalizador RESOURCE_MANAGER_VOLATILE.
Adicionando um Resource Manager a um TPS existente
Se você precisar adicionar um gerenciador de recursos adicional a um TPS existente, terá duas opções:
Seu novo gerenciador de recursos chama ZwCreateTransactionManager para criar seu próprio objeto do gerenciador de transações.
Use essa escolha se o gerenciador de recursos não se comunicar com outros gerenciadores de recursos no TPS.
Seu novo gerenciador de recursos chama ZwOpenTransactionManager para se conectar a um objeto existente do gerenciador de transações.
Use essa escolha se o gerenciador de recursos precisar se comunicar com outros gerenciadores de recursos no TPS. O gerenciador de recursos que chama ZwCreateTransactionManager deve compartilhar o GUID do objeto do gerenciador de transações, o nome do fluxo de log ou o nome do objeto para que outros gerentes de recursos possam chamar ZwOpenTransactionManager. Esses outros gerenciadores de recursos podem chamar ZwQueryInformationTransactionManager para obter informações adicionais sobre o objeto do gerenciador de transações.
Depois de adicionar o gerenciador de recursos ao TPS, os clientes que estão cientes do gerenciador de recursos poderão chamar a interface do cliente do gerenciador de recursos.