amily: Arial"> 

capaSQL21.JPG

 

Clique aqui para ler todos os artigos desta edição

 

XPrevail - Uma camada .NET de prevalência de objetos

Persistência simples e eficiente, inspeção remota de objetos e programação de aspectos

Fernando Vasconcelos Mendes – “FernandoVM”

Iniciarei o artigo explicando o conceito de prevalência, sua filosofia, funcionamento interno e empregos mais adequados. Posteriormente, vou expor o que é o projeto XPrevail, como ele pode ajudar em uma grande variedade de cenários e prover uma programação prática e moderna.

O que é prevalência?

O termo prevalência foi popularizado pelo brasileiro Klaus Wuestefeld e concretizado no projeto Prevayler, uma implementação em Java. Grande parte da filosofia empregada pela prevalência foi originalmente publicada por Andrew D. Birrell, Michael B. Jones e Edward P. Wobber em 1987 através de um artigo ainda hoje disponível em N>PrevalentSystem: classes definidas pelo usuário que devem referenciar todos os objetos de negócios da aplicação, ou seja, os objetos que serão persistidos. Os objetos por ela referenciados serão serializados quando for solicitado ao PrevalenceEngine um snapshot. Dessa forma, qualquer objeto fora dessa classe terá seu estado perdido. Grosseiramente, dependendo de seu design, ela pode representar um paralelo com uma tabela ou o próprio banco de dados. Aqui pode ser empregada facilmente uma variante do patterns DAO (ler Nota 1).

·         Snapshot: é o processo no qual o PrevalenceEngine serializa todos os PrevalentSystems, tal qual eles estão no momento da solicitação. Isso dá origem a um novo arquivo de snapshot, e torna desnecessária a leitura dos arquivos de operações anteriores (arquivos que guardam todas alterações realizadas nos objetos de negócio).

·         Operation: pelo conceito original proposto pela prevalência, toda alteração a ser realizada nos objetos mantidos por um PrevalentSystem (ou nele próprio) deve ser feita através de objetos de classes que implementam a interface IOperation definida pelo framework. Essas instâncias são passadas ao PrevalenceEngine para registro e execução (no projeto prevayler, a interface equivalente chama-se Transaction). Posteriormente veremos que o XPrevail pode tornar essa obrigatoriedade completamente transparente para o usuário.

 

Conhecidos os conceitos, podemos descrever um fluxo simples exemplificando claramente como se dá o processo de prevalência:

1.      Precisamos definir uma classe que manterá referência a nossos objetos Client. Ela será nosso PrevalentSystem e poderia chamar-se Clients.

2.      Deveremos declarar uma referência para o PrevalenceEngine e inicializá-la, momento no qual será exigida a informação de quais classes serão os PrevalentSystems. Naturalmente devemos informar apenas Clients, já que declaramos apenas ela.

3.      A inicialização do PrevalentSystem deve ser solicitada ao PrevalenceEngine, através da propriedade PrevalentSystem. Ela retornará uma instância da classe Clients com um estado exatamente igual ao da última execução (caso tenha havido uma).

4.      Como foi dito, qualquer alteração no PrevalentSystem para prevalecer é exigido que seja feita através de objetos de classes que implementem a interface IOperation. Assim, podemos declarar duas classes, uma chamada AddClient e outra chamada RemoverCliente, ambas implementando a interface IOperation. Respectivamente, elas seriam utilizadas para adicionar e remover objetos Cliente do PrevalentSystem. Ao longo desse texto poderemos ver o que o XPrevail propõe uma programação mais simples e intuitiva, não exigindo a criação dessas classes auxiliares.

5.      Para adicionar um cliente, precisamos agora criar uma instância da classe AddClient, passando em seu construtor as informações necessárias à execução de sua tarefa. Devemos então solicitar ao PrevalenceEngine que execute essa operação. Isso envolverá a serialização  do objeto  AddClient em um arquivo destinado ao  log de operações e posteriormente sua execução, onde de fato ocorrerá a adição do cliente.

6.      Assumindo termos executado várias vezes o item 5, além de eventualmente também termos realizado algumas remoções de clientes, teremos então um PrevalentSystem contendo uma determinada quantidade de objetos Client. O arquivo de log de operações conterá uma versão serializada de todos os objetos (que implementam IOperation) que efetuaram alterações no PrevalentSystem, exatamente na mesma ordem em que elas ocorreram.

7.      Caso nesse ponto ocorresse uma falha de energia. Nossa aplicação deveria ser reposta no ar, tão logo o ambiente tivesse sido restabelecido. No momento da inicialização do PrevalenceEngine, ele irá ler todos os arquivos de log de operações gerados. Des-serializará todos os objetos contidos nos arquivos e irá executá-los novamente. Atente para o detalhe que os objetos mantidos nesses arquivos são os da classe AddClient, não os da classe Client. O PrevalenceEngine está constantemente registrando as alterações realizadas nos objetos de negócios, não os objetos de negócio em si.

8.      Tendo a aplicação voltado ao ar e seu estado anterior recuperado, poderíamos gerar mais algumas alterações no PrevalentSystem e solicitar um snapshot. Nesse momento o PrevalenceEngine irá gerar um arquivo novo, não um de operações, mas um especificamente para o snapshot. Esse arquivo conterá uma versão serializada do PrevalentSystem inteiro, ou seja, efetivamente de todos os objetos de negócio. Digamos que após o snapshot, fizemos mais algumas alterações no estado do PrevalentSystem e ocorreu outra falha de energia.

9.      Quando nossa aplicação solicitar a inicialização do PrevalenceEngine, ele buscará pelo mais recente snapshot gerado. De posse dele, ele des-serializará seu conteúdo e obterá uma versão do PrevalentSystem. Feito isso, pegará todos os arquivos de log de operações posteriores ao último snapshot e re-executará todas as operações em cima do PrevalentSystem obtido anteriormente. Isso resultará em um PrevalentSystem tal qual existia antes da falha, da forma mais otimizada possível.

 

Dentre as principais vantagens do uso de prevalência, podemos citar o grande ganho de performance para consultas e a drástica redução de custos de uma solução como: custos de servidor para o banco de dados (hardware), licenças do software servidor de banco de dados e custo operacional de manutenção, dentre outros. ...

Quer ler esse conteúdo completo? Tenha acesso completo