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

Uma proposta de Clean Architecure com Modelo de Atores

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