Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Qualquer TPS ( sistema de processamento de transações ) que use o KTM (Kernel Transaction Manager) e o CLFS ( Common Log File System ) deve conter os seguintes componentes importantes:
Um KTM ( gerenciador de transações )
A KTM controla o estado de cada transação e coordena as operações de recuperação após uma falha no sistema.
Um ou mais gerenciadores de recursos
Os gerenciadores de recursos que você fornece gerenciam os dados associados a cada transação.
Um ou mais fluxos de log do CLFS
O gerenciador de transações e os gerenciadores de recursos usam fluxos de log CLFS para registrar informações que podem ser usadas para confirmar, reverter ou recuperar uma transação.
Um ou mais clientes transacionais
Normalmente, cada cliente transacional do TPS pode criar uma transação, executar operações em dados no contexto da transação e, em seguida, iniciar uma operação de confirmação ou reversão para a transação.
Este artigo apresenta um TPS simples com um gerenciador de recursos, um TPS mais complexo que contém vários gerenciadores de recursos e alguns outros cenários de TPS.
A seção Usando KTM fornece informações detalhadas sobre como usar o KTM para criar componentes TPS.
TPS simples
Um TPS simples pode ser composto por KTM, um gerenciador de recursos e CLFS. Os clientes transacionais podem se comunicar com o gerenciador de recursos por meio de uma interface fornecida pelo gerenciador de recursos.
Por exemplo, suponha que você queira criar um sistema de gerenciamento de banco de dados. Você deseja que os clientes do sistema acessem o banco de dados abrindo um identificador para um objeto de banco de dados, executando operações de leitura e gravação no objeto e fechando o identificador do objeto.
Agora suponha que você queira que conjuntos de operações de leitura e gravação ocorram atomicamente para que outros usuários do sistema vejam apenas o resultado final. Você pode atingir essa meta projetando um TPS que permite aos clientes associar conjuntos de operações de banco de dados a uma transação.
Seu sistema deve incluir um gerenciador de recursos que gerencia os dados no banco de dados em resposta a solicitações de leitura e gravação de clientes. Esse gerenciador de recursos pode exportar uma API (interface de programação de aplicativo) que permite aos clientes associar uma transação a um conjunto de operações de leitura e gravação.
Quando você carrega o gerenciador de recursos, ele deve se registrar no KTM chamando ZwCreateTransactionManager e ZwCreateResourceManager. Em seguida, o gerenciador de recursos pode participar de transações.
Talvez você queira que o gerenciador de recursos dê suporte a um conjunto de funções que permite que os clientes criem objetos de dados, leiam e escrevam dados associados aos objetos de dados e fechem os objetos de dados. O pseudocódigo a seguir mostra um exemplo de sequência de código de um cliente.
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);
Antes que um cliente possa chamar a rotina CreateDataObject do gerenciador de recursos, o cliente deve criar um objeto de transação chamando a rotina ZwCreateTransaction da KTM e obter o identificador do objeto de transação chamando ZwQueryInformationTransaction.
Quando o cliente chama a rotina CreateDataObject do gerenciador de recursos, o cliente passa o identificador do objeto de transação para o gerenciador de recursos. O gerenciador de recursos pode chamar ZwOpenTransaction para obter um identificador para o objeto de transação e, em seguida, pode chamar ZwCreateEnlistment para registrar sua participação na transação.
Neste ponto, o cliente pode começar a executar operações no objeto de dados. Como o cliente forneceu um identificador de transação quando criou o objeto de dados, o gerenciador de recursos pode atribuir todas as operações de leitura e gravação à transação.
O gerenciador de recursos deve registrar todos os resultados das operações de dados especificadas pelo cliente sem tornar os resultados permanentes. Normalmente, o gerenciador de recursos usa CLFS para registrar os resultados da operação em um fluxo de log de transações.
Quando o cliente termina de chamar o gerenciador de recursos para executar operações transacionais, ele chama a rotina ZwCommitTransaction da KTM. Neste ponto, a KTM notifica o gerenciador de recursos de que ele deve tornar as operações permanentes. Em seguida, o gerenciador de recursos move os resultados da operação do fluxo de log para o meio de armazenamento permanente dos dados. Por fim, o gerenciador de recursos chama ZwCommitComplete para informar à KTM que a operação de confirmação está concluída.
O que acontece se o gerenciador de recursos relatar um erro para uma das chamadas do cliente para ReadData ou WriteData? O cliente pode chamar ZwRollbackTransaction para reverter a transação. Como resultado dessa chamada, a KTM notifica o gerenciador de recursos de que ele deve restaurar os dados para seu estado original. Em seguida, o cliente pode criar uma nova transação para as mesmas operações ou pode optar por não continuar.
O pseudocódigo a seguir mostra um exemplo de uma sequência mais detalhada das operações transacionais de um cliente.
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;
O que acontece se o sistema falhar após a criação da transação, mas antes de ser confirmada ou revertida? Sempre que o gerenciador de recursos é carregado, ele deve chamar ZwRecoverTransactionManager e ZwRecoverResourceManager. Chamar ZwRecoverTransactionManager faz com que a KTM abra seu fluxo de log e leia o histórico de transações. Chamar ZwRecoverResourceManager faz com que a KTM notifique o gerenciador de recursos de todas as transações inscridas que estavam em andamento antes da falha e quais transações o gerenciador de recursos deve, portanto, recuperar.
Se um cliente transacional chamou ZwCommitTransaction para uma transação antes da falha e começou a executar operações de confirmação para a transação, o gerenciador de recursos deverá ser capaz de restaurar o estado da transação até o ponto imediatamente antes da falha. Se o cliente não estiver pronto para confirmar a transação antes da falha, o gerenciador de recursos poderá descartar os dados e reverter a transação.
Para obter mais informações sobre como escrever clientes transacionais, consulte Criando um cliente transacional.
Para obter mais informações sobre como escrever gerenciadores de recursos, consulte Criando um Gerenciador de Recursos.
Vários gerenciadores de recursos em um TPS
Agora suponha que o TPS permita que os clientes modifiquem informações em dois bancos de dados separados em uma única transação, de modo que a transação seja bem-sucedida somente se as modificações de ambos os bancos de dados forem bem-sucedidas.
Nesse caso, o TPS pode ter dois gerenciadores de recursos, um para cada banco de dados. Cada gerenciador de recursos pode exportar uma API que os clientes podem usar para acessar o banco de dados do gerenciador de recursos.
O pseudocódigo a seguir mostra como um cliente pode criar uma única transação que contenha operações em dois bancos de dados compatíveis com dois gerenciadores de recursos.
Neste exemplo, o cliente lê dados do primeiro banco de dados e os grava no segundo banco de dados. Em seguida, o cliente lê dados do segundo banco de dados e os grava no primeiro banco de dados. (O primeiro gerenciador de recursos exporta funções que começam com rm1 e o segundo gerenciador de recursos exporta funções que começam com 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;
Como o cliente passa o mesmo identificador de transação para ambos os gerenciadores de recursos, ambos os gerenciadores de recursos podem chamar ZwOpenTransaction e ZwCreateEnlistment para se inscreverem na transação. Quando o cliente eventualmente chama ZwCommitTransaction, a KTM notifica cada gerenciador de recursos de que o gerente deve tornar as operações permanentes e cada gerenciador de recursos chama ZwCommitComplete quando ela é concluída.
Outros cenários de TPS
O KTM dá suporte a outros cenários de TPS. Por exemplo, os seguintes cenários descrevem componentes que um TPS pode conter:
Um gerenciador de recursos que gerencia vários bancos de dados.
A API do gerenciador de recursos pode permitir que os clientes abram e acessem mais de um banco de dados por vez e o cliente pode combinar acessos a vários bancos de dados em uma única transação.
Um gerenciador de recursos com uma API que os clientes chamam e outros gerenciadores de recursos com APIs que o primeiro gerenciador de recursos chama.
O cliente se comunica apenas com o primeiro gerenciador de recursos. Quando esse gerenciador de recursos processa solicitações de um cliente, ele pode acessar os gerenciadores de recursos adicionais, conforme necessário, para processar as solicitações do cliente. Por exemplo, um gerenciador de recursos gerencia um banco de dados acessível ao cliente que requer operações de backup ou verificação de dados de um segundo gerenciador de recursos que os clientes não podem acessar.
Um cliente e um gerenciador de recursos existentes que não usam KTM, integrado a um conjunto adicional de gerenciadores de recursos que usam KTM.
Nesse caso, normalmente você precisa modificar o gerenciador de recursos existente para que ele se torne um gerenciador de transações superior que se comunique com o KTM.