NHiLo - Gerador de chaves primárias (substitutas)

Hoje subi pela primeira vez um pacote Nuget para o seu repositório oficial. Trata-se de um pequeno componente de código aberto que eu fiz para permitir a geração de chaves primárias para registros sem a dependência do banco de dados para isso. Leia-se: NÃO PRECISAR MAIS DE COLUNAS DE AUTO-NUMERAÇÃO COMO IDENTITY.

O uso de colunas do tipo identity são uma das poucas coisas que eu torço o nariz sem antes saber o motivo porque foi escolhido essa abordagem para chaves substitutas. Não gosto porque esse tipo de campo dificulta se precisarmos manter bases sincronizadas, pois o ID da coluna pode ser diferente em cada uma delas.

Este componente é uma implementação isolada do algoritmo HiLo, famoso no NHibernate. Não é nada novo no mundo do desenvolvimento (e todo o crédito para os desenvolvedores do Hibernate/NHibernate), mas que não encontrei uso disponível fora desse framework de ORM. Inclusive esse foi o motivo de eu criá-lo: poder usar o HiLo em uma situação que eu não posso trabalhar com ferramentas de ORM por restrições do cliente :-( .

Ele trabalha separando uma faixa de chaves primárias que podem ser definidas pela própria aplicação. Isso quer dizer que qualquer dado é gerenciado totalmente pela aplicação, o repositório não é responsável por definir nada. Funciona assim: digamos que nossas faixas de chaves disponíveis variam de 100 em 100 registros. Grava-se numa tabela de controle o valor 1. Então a aplicação vai usando as chaves disponíveis, sempre incrementando 1 (veja que isso é feito sem interferência do repositório, chave 1, 2, 3 e assim por diante). Quando a aplicação chegar na última faixa disponível, vamos novamente para a tabela de controle e gravamos 2 (faixa de 101 até 200). Se durante o uso da aplicação outra instância da mesma necessitar de uma faixa de dados, sem problemas, ela vai nessa tabela e grava 3. A primeira instância continua usando a faixa 2, e quando necessitar de uma faixa nova, ela receberá a 4.

Bom, alguns podem argumentar que ainda assim há a dependência com o repositório, pois é nele que são armazenados os dados de controle. Sim, existe essa dependência, entretanto quem efetivamente define o valor de uma nova chave disponível não é o repositório, mas sim a aplicação.

Apesar de existir um momento em que há uma ida ao banco de dados, ela ocorre esporadicamente, e na maioria das vezes a geração da nova chave é uma operação rápida, sem ônus no desempenho da aplicação. Veja por exemplo o gráfico abaixo, que peguei de um teste que fiz. Os "picos" ocorrem de 100 em 100, exatamente no momento em que se busca um novo valor de faixa. O valor deles gira em torno de 2 milissegundos...

Gráfico mostrando poucos picos de "demora" na geração das chaves

O código de exemplo é bem simples. Basicamente criamos um factory (HiLoGeneratorFactory) e obtemos o gerador de chaves para determinada entidade.

[TestMethod]
    public void ShouldReturnAValidKey()
    {
    // Arrange
    var factory = new HiLoGeneratorFactory();
    // Act
    var generator = factory.GetKeyGenerator("dummy4");
    var key1 = generator.GetKey();
    var key2 = generator.GetKey();
    // Assert
    Assert.IsTrue(key1 > 0);
    Assert.IsTrue(key2 > 0);
}


Não é necessária nenhuma configuração adicional para o projeto funcionar, basta o arquivo config da aplicação possuir pelo menos uma string de conexão (faz sentido, pois precisamos acessar o banco de dados de alguma forma). NHiLo irá considerar sempre a última string de conexão para seu uso. Existe a possibilidade de configurar algumas coisas, como se quisermos escolher outra string de conexão ou mesmo o tamanho da faixa, mas isto vou deixar para outro post.

Além disso, foi testado apenas o uso do NHiLo no SQL Server e no SQL Server CE (a definição do tipo do repositório varia com o provider da string de conexão). A implementação para MySQL está pronta mas eu não testei, e a para Oracle ainda não começou a ser feita.


Bom, quem quiser testar a versão que está disponível no Nuget é só procurar por NHiLo, lembrando que é um pacote de pré-release (versão beta).

Tela mostrando o Nuget com o NHiLo disponibilizado.


Além disso, os fontes desse projeto estão hospedados no Codeplex, quem quiser olhar como foi feito ou mesmo contribuir é só entrar em contato comigo!


Abraços e até a próxima!

Comentários

Postagens mais visitadas deste blog

Trocando configurações padrão do Live TIM

Testes automatizados em sistemas autenticados com certificados digitais, usando Selenium e PhantomJS

Uma proposta de Clean Architecure com Modelo de Atores