O que é número consecutivo
Um número consecutivo é simplesmente um número que segue a ordem natural dos inteiros, um após o outro, sem lacunas. Se você tem o número 7, o próximo consecutivo é 8. Se começa no 15, a sequência é 15, 16, 17, 18 e assim por diante. O conceito parece trivial até você precisar implementar isso num sistema de faturamento ou num controle de documentos, aí as coisas complicam. No dia a dia, número consecutivo aparece em NF-e, CT-e, notas promissórias, controles de estoque, números de processo judicial. Tudo isso depende de uma sequência que não pode se repetir e que obrigatoriamente precisa ser crescente. O problema real não é entender o conceito, é garantir que essa sequência funcione em produção sem criar conflito de dados ou perda de registos.
como definir e usar número consecutivo num sistema
A forma mais comum de implementar um contador consecutivo é usando uma tabela dedicada, com uma linha por tipo de documento e um campo inteiro que armazena o último número atribuído. Quando um novo registro precisa ser criado, você faz um SELECT FOR UPDATE naquela linha, lê o valor, incrementa em 1, gravas de volta e já tem o número. O trancamento da linha durante a transação é o que evita que dois processos peçam o mesmo número ao mesmo tempo. Sem isso, você vai ter colisão. E colisão em número consecutivo em nota fiscal é dor de cabeça com o provedor de assinatura e a SEFAZ. Eu já tive um caso em que um serviço de processamento de NF-e tinha três instâncias rodando simultâneamente e o contador estava num campo simples de UPDATE normal, sem bloqueio. O resultado foram notas com o mesmo número consecutivo, duas delas rejeitadas pela SEFAZ e uma terceita que foi autorizada mas ficou duplicada no banco. Eu resolvi migrando o contador para uma tabela separada com tranca exclusiva via SELECT FOR UPDATE NO KEY, mais uma função PL/pgSQL que envolvia tudo numa única transação. A mudança foi de alguns segundos de falha esporádica para zero colisões em semanas de operação.
Outro detalhe que muitos esquecem: número consecutivo não precisa começar do 1. Você pode definir um valor inicial arbitrário, geralmente vinculado ao ano fiscal ou ao código da empresa. No Brasil, por exemplo, o número do documento fiscal costuma seguir uma estrutura que inclui código da UF, código do emitente e sequência numérica. A parte sequencial é o consecutivo, e ela zera a cada ano ou continua crescendo dependendo do modelo. Isso é importante porque some automaticamente quando você precisa gerar lote de envio ou auditoria.
armadilhas que ninguém conta
A primeira armadilha é achar que um campo SERIAL ou AUTO INCREMENT do banco de dados resolve o problema. Ele resolve parte, sim, mas só garante unicidade dentro daquela tabela. Não garante a ordem consecutiva que a legislação ou o regulamento interno exige. Se você cancelar um documento, o autoincrement avança mesmo assim e cria um buraco na sequência. Buraco em sequência consecutiva de nota fiscal é problema. A SEFAZ pode questionar, e o auditor vai questionar muito mais. A segunda armadilha é confundir sequência lógica com número expedido. Às vezes o sistema gera um ID interno que é consecutivo, mas o número que vai para o documento público é derivado de outra regra. Isso é aceitável desde que fique claro na documentação e nos relatórios. Caso contrário, você acaba tendo dois números diferentes para o mesmo registro e qualquer comparação manual vira um inferno de planilha.
👉 Clique no botão abaixo para saber mais sobre o assunto!
Um terceiro ponto que passa despercebido é a questão da reposição de numeração. Se você precisa reimprimir uma nota cancelada ou reemitida, o número consecutivo já foi consumido. Em muitos casos a solução é manter um histórico de numerações inutilizadas e permitir reposição apenas mediante autorização, ou então gerar um novo número subsequente e vincular o antigo como referência. A escolha depende do regulamento aplicável ao seu documento.
como validar se a sequência está correta
Uma verificação prática é rodar um query que encontre lacunas. Você compara o número esperado com o número existente e sinaliza onde há diferença. Num banco PostgreSQL, por exemplo, você pode usar uma window function com ROW_NUMBER() e subtrair do valor real. Se o resultado for maior que zero em alguma linha, tem lacuna. Lacunas indicam cancelamentos, exclusões manuais ou erros de implementação. Depender exclusivamente de um log manual é arriscado, porque logs também podem ser truncados ou não refletir todas as operações. Outra validação útil é checar a continuidade entre exercícios fiscais diferentes. Se sua sequência reinicia todo ano, você precisa garantir que o novo ano comece exatamente no número 1 e que não haja sobreposição com o ano anterior. Já vi sistemas em que o reinício acontecia no primeiro dia útil do ano seguinte, criando uma janela onde duas notas podiam ter o mesmo número em anos diferentes. Esse erro é difícil de detectar em auditoria, porque os relatórios normalmente são gerados por exercício separado.
alternativas quando o convencional não funciona
Se o seu cenário envolve alta concorrência e milhares de requisições por segundo, o modelo de tabela de contador com SELECT FOR UPDATE pode se tornar gargalo. Nesse caso, uma alternativa é usar um buffer de números alocados por lote. Você reserva, por exemplo, 500 números de uma vez, deixa-os em memória ou numa tabela temporária, e consome sem tranca a cada nova emissão. Quando o lote acaba, você solicita o próximo bloco. Isso reduz drasticamente a contenção e é amplamente usado em sistemas de grande porte. O risco é que, se o sistema cair no meio do consumo do lote, você pode ter números alocados mas não utilizados, o que gera lacuna. Você precisa decidir se aceita essa lacuna ou se implementa um mecanismo de recuperação. Em cenários onde a sequência precisa ser absolutamente contínua e sem lacuna, a única via segura é o contador tradicional com tranca. Nada substitui a garantia de atomicidade. Tentar otimizar demais nesse caso costuma criar problemas que aparecem apenas em pico de carga, exatamente quando você mais precisa que funcione.
resumo prático
Implementar número consecutivo parece simples, mas exige atenção a três coisas principais: tranca adequada para evitar colisão, gestão de cancelamentos para justificar lacunas, e validação periódica da sequência. Se o sistema for de baixo volume, um contador direto na tabela já resolve. Se for alto volume, considere alocação em lotes com política clara de recuperação. O que não funciona de jeito nenhum é confiar em autoincremento puro e torcer para que não dê problema. O problema sempre dá, e geralmente quando você menos espera.