Atenção: esse artigo tem uma palestra complementar. Clique e assista!
Neste artigo veremos o que é o padrão CpBT (Conversation per Business Transaction) e como aplicá-lo em projetos NHibernate, com o auxílio do uNhAddins.
Para que serve
CpBT é um padrão utilizado quando precisamos implementar transações de longa duração em nossas aplicações. Como veremos, com esse padrão uma transação é implementada através do conceito de conversação.
Em que situação o tema é útil
Imagine um e-commerce qualquer, onde o usuário vai selecionando os itens que quer adicionar ao seu carrinho de compras virtual. Com o padrão CpBT e o uNhAddins, você pode modelar uma transação para tratar essa situação de forma transparente, como uma transação de longa duração.
Resumo do DevMan
A forma mais comum de se pensar em
transações é na sua forma mais atômica. Um simples INSERT ou UPDATE no banco, ou
até mesmo um conjunto de comandos SQL que executamos em uma simples chamada.
Acontece que nem todas as aplicações são compostas de transações dessa
simplicidade. Muitas aplicações (talvez a maioria), precisam implementar
transações de negócio mais complexas, que podemos chamar de transações de longa
duração. São aquelas operações que geralmente passam por várias páginas Web, ou
janelas Windows. Uma das formas de se tratar esse problema é através do padrão
conhecido como CpBT, Conversation per Business Transaction. Veremos neste artigo
o que é esse padrão e como usá-lo em aplicações com NHibernate e o uNhAddins.
Autores: Rodrigo Sendin e Paulo Quicoli
Como você resolve transações complexas em sua aplicação? Imagine aquela tela de Pedido de Venda, onde vão sendo armazenados os itens dos pedidos que o usuário vai selecionando? As condições de pagamento, detalhes de desconto, transportadora, cálculos fiscais etc.? Como você controla isso na hora de persistir os dados no banco? Se tudo ocorrer bem, como você garante que a operação inteira será persistida, e no caso de algum erro, que nada seja persistido no banco?
Esse problema é antigo e de muitas soluções possíveis. Quem tem experiência com bancos de dados relacionais sabe da importância dessa questão e também sabe que o próprio banco de dados dá algumas soluções para o problema. Mas como resolver isso em uma aplicação desenvolvida com orientação a objetos, que faz uso de uma ferramenta de mapeamento objeto/relacional, como é o caso do NHibernate?
Para isso temos um padrão chamado CpBT, que é a sigla para Conversation per Business Transaction. Esse padrão pode ser adotado com o uso de um framework chamado uNhAddins. O uNhAddins é um projeto paralelo ao NHibernate, que trata de algumas questões que fogem do escopo principal do NHibernate.
Ou seja, o uNhAddins é um framework complementar ao NHibernate, que nos traz várias soluções para nos auxiliar ainda mais no desenvolvimento de nossas aplicações, como é o caso do padrão CpBT. Na seção Links, no final deste artigo, você encontrará o endereço do projeto uNHAddins, onde você pode baixar os binários, e até ter acesso ao código fonte.
Nos tópicos seguintes veremos como utilizar o uNHAddins para aplicar o padrão CpBT em uma aplicação com NHibernate. Veremos isso através de um exemplo prático.
Projeto conversa
Imagine uma aplicação onde precisamos persistir uma Conversa, ou um “Bate Papo”. A conversa é iniciada e as pessoas vão falando entre si, até que ela se encerra. Ao finalizar a conversa, podemos optar por abortá-la, descartando todo o seu conteúdo, ou por salvá-la, persistindo todo o histórico da conversa em um banco de dados.
Sabemos que você pode implementar esse exemplo mantendo todo o histórico em memória e no final simplesmente encapsular uma chamada que irá persistir tudo de uma vez no database. Mas pensando no padrão CpBT, a cada nova fala da conversa nós vamos até a sessão do NHibernate e pedimos para que ele salve a fala. Porém, a conversa completa só será persistida no final, se assim desejarmos. E no caso de a conversa ser abortada, nada será persistido no banco, e os dados que ficaram na sessão do NHibernate serão descartados.
Esse exemplo será feito usando o Visual Studio 2010, portanto abra-o e crie uma nova Solution em branco, chamada Conversa. Dentro dessa Solution vamos criar quatro projetos, que irão representar quatro camadas de uma aplicação. Como você pode ver na Figura 1, temos um projeto Class Library chamado Conversa.Dominio, onde teremos o nosso pequeno modelo de entidades e as interfaces que irão definir o Repositório e Serviço que iremos utilizar. Temos outros dois projetos do tipo Class Library para tratar respectivamente da implementação do Repositório em NHibernate, e do Serviço, que é onde o CpBT é implementado com o uNhAddins. Por fim temos um projeto Console Application que será utilizado para fazermos os nossos testes.
Figura 1. Estrutura de projetos do exemplo Conversa
Domínio
Como de costume vamos começar modelando o domínio da nossa aplicação, iniciando pelas entidades. Como você pode conferir no diagrama de classes da Figura 2, temos apenas duas entidades neste domínio. Uma entidade chamada Papo, que é a conversa em si, e a outra chamada Fala, que representará as falas que ocorrem durante uma conversa.
Figura 2. Diagrama de entidades do domínio
Veja que também temos um Enum chamado Situacao, que indica quais os possíveis status de uma conversa. Como podemos ver uma conversa pode estar acontecendo, pode estar concluída e, portanto persistida no banco. E por último uma Conversa também pode ser abortada, tendo todo o seu histórico descartado. Confira no código a seguir como fica a implementação do Enum Situacao:
namespace Conversa.Dominio.Entidades
{
public enum Situacao
{
Acontecendo, Abortada, Concluida
}
}
As nossas duas entidades implementam uma interface chamada IEntidade, que você pode conferir a seguir:
...