Pergunta

Estou tentando alcançar algum tipo de comportamento de transação aninhado usando o controle de transações e as opções de FlushMode da Nhibernate, mas as coisas ficaram um pouco confusas após muita leitura; portanto, qualquer confirmação sobre os fatos que listar abaixo será muito útil.

O que eu quero é abrir uma grande transação que se divida em pequenas transações. Imagine o seguinte cenário:

  • O TX1 abre um TX e insere o histórico de uma pessoa;
  • O TX2 abre um TX e atualiza o nome dessa pessoa para P2;
  • TX2 COMPRIMENTO;
  • O TX3 abre um TX e atualiza o nome dessa pessoa para P3;
  • Rollacks TX3;
  • TX1 COMPRIMENTO;

Eu gostaria de ver o NH enviando a inserção e a atualização do TX2 para o banco de dados, apenas ignorando o que o TX3, pois foi revertido.

Tentei usar o FlushMode = nunca e apenas a liberação da sessão após o início do início/cometidos/rollacks adequados, mas o NH sempre atualiza o banco de dados com o estado final do objeto, independente de commits e reversão. Isso é normal? O NH realmente ignora o controle transacional ao trabalhar com FlushMode = nunca?

Também tentei usar o FlushMode = Commit e abrir as transações aninhadas, mas descobri que, porque o ADO.NET, as transações aninhadas são, na verdade, sempre a mesma transação.

Observe que não estou tentando alcançar um comportamento "tudo ou nada". Estou olhando mais para uma maneira de salvamento de trabalho. Existe uma maneira de fazer isso (SavePoints) com o NH?

Agradeço antecipadamente.

Filipe

Foi útil?

Solução

Só para não deixar essa pergunta em aberto para sempre, postarei a solução que adotamos.

Temos uma unidade de trabalho como contêiner que gerencia o comportamento da transação aninhada. Dependendo do tipo de tratamento que queremos, ele cria (ou não) novas sessões. Por exemplo:

  • Continue o erro: se quisermos que, mesmo que em um erro de transação, os outros cometam, o contêiner da UOW usa sessões diferentes para cada "transação" e libera cada TX no final de seu trabalho;
  • Rollback no erro: se queremos isso em uma reversão de sessão (devido a um erro ou uma reversão comercial), todas as outras transações são revertidas, o contêiner Uow usa a mesma sessão para todas as transações aninhadas e reverte todos no final.

É importante dizer que a "transação" que essa Uow manipula não é a transação NH (ADO.NET) diretamente. Criamos uma abstração de uma transação para que o Código de Manipulação "votos" se nossa transação pudesse ser cometida ou revertida, mas a ação real ocorre no final de tudo, com base na estratégia de erro selecionada.

Sabemos que esse uso não é muito comum e se encaixa apenas em cenários específicos (no nosso caso, é um cenário de integração com processamento em lote), então agora vou postar o código. Se alguém pensa que essa implementação pode ajudar, envie -me uma mensagem e ficarei feliz em compartilhar o código.

Cumprimentos,

Filipe

Outras dicas

O Nibernate não suporta transações aninhadas. Cada isamento pode ter no máximo uma transação ativa. Não tenho certeza do que você; está tentando realizar, porque seu cenário de exemplo não faz sentido para mim. Cometer a transação 1 após a inserção teria o mesmo efeito.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top