Configurando transações

O atributo transaction é uma propriedade declarativa que gerencia automaticamente as transações para o desenvolvedor do componente. Ao definir esse atributo, você elimina a necessidade de usar controles de transação explícitos em seu componente.

COM+ usa o atributo transaction do componente para determinar o tipo de proteção de transação necessária para cada objeto que ele ativa. Dependendo de sua necessidade, um objeto pode compartilhar a transação de seu chamador, exigir uma nova transação ou operar sem proteção de transação.

COM+ fornece os seguintes valores de atributo de transação:

Desactivado

Em geral, você deve definir esse valor de atributo somente quando tiver certeza de que o componente nunca acessa um gerenciador de recursos. Quando você desabilita o atributo de transação, COM+ ignora os requisitos transacionais do componente na determinação do posicionamento de contexto do objeto. Como resultado, o objeto pode compartilhar o contexto (e a transação) de seu chamador. Ao migrar um componente COM para COM+, você deve desabilitar o atributo transaction para manter o mesmo comportamento transacional que o componente COM não configurado.

Observação

Um componente não configurado é um componente COM que não foi instalado em um aplicativo COM+.

Não compatível

Quando você define esse valor de atributo, COM+ garante que qualquer objeto criado a partir do componente nunca participe de uma transação, independentemente do status transacional de seu chamador. Ao declarar esse valor, você garante que um objeto não vote na transação de seu chamador nem possa iniciar uma transação própria. Não suportado é o valor padrão para todos os componentes.

Suportado

Quando você define esse valor de atributo, COM+ garante que qualquer objeto criado a partir do componente participe de uma transação, se houver. Você declara esse valor quando deseja que um objeto compartilhe a transação de seu chamador sem exigir uma transação própria.

Necessário

Quando você define esse valor de atributo, COM+ garante que qualquer objeto criado a partir do componente seja transacional. Quando COM+ ativa um objeto com a configuração Required, ele examina o status transacional de seu chamador. Se o chamador tiver uma transação, o novo objeto será incluído na transação atual. Caso contrário, COM+ inicia uma transação, tornando o novo objeto a raiz da transação. Essa é a configuração preferencial para um componente que executa atividades de recurso porque ajuda a fornecer proteção de transação para essas atividades.

Requer Novo

Quando você define esse valor de atributo, COM+ garante que todos os objetos criados a partir do componente devem participar de uma nova transação como a raiz da transação, independentemente do status transacional do chamador. COM+ inicia automaticamente uma nova transação que é diferente da transação do chamador.

Observação

COM+ não oferece suporte a transações aninhadas. Quando um objeto transacional chama outro componente marcado como Requer Novo, COM+ cria um limite transacional independente para o objeto recém-ativado. A segunda transação não pode afetar a primeira transação, a menos que a primeira transação anote explicitamente os resultados da segunda transação e modifique seu voto com base nesses resultados.

Dependências de atributo de transação

A tabela a seguir mostra as características de cada valor de atributo de transação COM+, incluindo o efeito do valor nas características da transação. COM+ impõe a ativação JIT e sincronização para todos os componentes de transação.

Valor do atributo Nova Transação Transação do Cliente Raiz da transação Ativação JIT Sincronização
Desabilitado
Nunca
Talvez
Nunca
Opcional
Opcional
Sem suporte
Nunca
Nunca
Nunca
Opcional
Opcional
Com suporte
Nunca
Se o cliente tiver transação
Nunca
Obrigatório
Obrigatória
Obrigatório
Talvez
Se o cliente tiver transação
Se o cliente não tiver nenhuma transação
Obrigatório
Obrigatório
Requer novo
Sempre
Nunca
Sempre
Obrigatório
Obrigatório

Limites da transação

Uma transação tem um começo, um fim e ocorre exatamente uma vez. Durante sua execução, uma transação pode chamar um recurso, como um banco de dados ou fila, para realizar uma ou mais tarefas. Cada recurso está dentro do limite da transação. Todos os recursos dentro de um limite de transação, que pode abranger vários limites de processo e computador, compartilham uma única transação. É importante gerenciar a consistência entre esses limites de processo e computador.

O COM+ garante a consistência gerenciando os limites de transação automaticamente, com base no valor do atributo de transação definido para cada componente. Uma transação COM+ flui automaticamente para objetos instruídos a participar de uma transação e ignora objetos instruídos a executar fora de uma transação. COM+ não oferece suporte a transações aninhadas. Em vez disso, as transações COM+ são distintas e de curta duração.

O primeiro objeto em um limite de transação é especial para a transação e é chamado de objeto raiz da transação. Pode haver apenas um objeto raiz em uma transação. Todos os outros objetos na hierarquia transacional sob o objeto raiz são chamados de objetos interiores.

Mapeando transações

Uma maneira de garantir que um objeto seja incluído no limite de transação correto é mapear suas transações antes de começar a gravar seus componentes. Mapeando transações, você pode determinar a melhor configuração para cada componente gravado. Quanto mais certo você estiver sobre como seus componentes devem ser usados, mais fácil será selecionar o valor correto do atributo de transação.

Em tempo de execução, COM+ examina o atributo transaction para determinar se um objeto deve ser a raiz de uma nova transação, ser criado em uma transação existente ou ser criado como um objeto não transacional.

A ilustração a seguir mostra um possível mapeamento de transações. Na ilustração, o cliente cria o Objeto 1, que requer uma transação. Como nenhuma transação existe, COM+ cria a Transação 1 e coloca o Objeto 1 nela como o objeto raiz. O Objeto 1 cria o Objeto 2, que oferece suporte a transações e, portanto, é colocado na Transação 1. O Objeto 2 cria o Objeto 3, que não oferece suporte a transações e, portanto, é colocado fora de todas as transações. O Objeto 2 também cria o Objeto 4, que requer uma transação e, portanto, é colocado na Transação 1. O Objeto 3 cria o Objeto 5, que oferece suporte a transações. No entanto, como o Objeto 5 é criado por um objeto que não existe dentro de uma transação, ele também é colocado fora de todas as transações. O Objeto 4 cria o Objeto 6, que requer uma nova transação, portanto, COM+ cria a Transação 2 e coloca o Objeto 6 nele como o objeto raiz. O Objeto 6 cria o Objeto 7, que oferece suporte a transações e, portanto, é colocado na Transação 2.

Diagram that shows a client interaction with Transaction 1 and Transaction 2.

A ilustração anterior mostra duas áreas problemáticas potenciais. Primeiro, a maior parte do trabalho é dividida entre duas transações distintas. Se a Transação 1 falhar depois que o Objeto 4 criar o Objeto 6, a Transação 2 será executada sem ser afetada pelo resultado da Transação 1. Se esse resultado não for intencional, talvez você prefira dobrar as operações de ambas as transações em uma única transação, o que pode ser feito alterando o atributo de transação do Objeto 6 para Obrigatório.

A ilustração de mapeamento também mostra que o Objeto 3 e o Objeto 5 não são transacionais, sendo executados completamente fora do escopo das Transações 1 e 2. Se o Objeto 5 atualizar dados persistentes, convém reconsiderar seu status não transacional. O objeto 5 pode ser colocado em uma transação alterando seu atributo de transação para Required.

Definindo o atributo de transação