» Início » Desenvolvimento » Banco de dados e SQL » SQL Server: Geração de seqüenciais de forma automática
 
Avaliação: | Publicado em: 20/09/2007
SQL Server: Geração de seqüenciais de forma automática


Comportamentos Adversos

Quando se opta pela utilização do Identity, é bem provável imaginar que a coluna não poderá ter valores repetidos e que os números sempre serão gerados na ordem de acordo com o início (SEED) e o incremento (INCREMENT) previamente definidos. Embora isso seja verdade em muitas situações, o Identity não pode garantir esse comportamento.

GAPs

Imagine que no exemplo 1, a cliente Noemy deva ser excluída do banco de dados e que logo em seguida seja cadastrada a cliente Márcia. A cliente Noemy tinha o ID igual a 4 e como ela foi excluída, o último Identity é igual a 3. O natural é esperar que o próximo cliente utilize o ID igual a 4.

-- Exclusão (ClienteID = 4)
DELETE FROM tblClientes WHERE ClienteNome = 'Noemy'

-- Verificação do Identity
SELECT
    ClienteID, ClienteNome
FROM
    tblClientes

-- Nova Inserção
INSERT INTO tblClientes (ClienteNome) VALUES ('Márcia')

-- Verificação do Identity
SELECT
    ClienteID, ClienteNome
FROM
    tblClientes

No entanto, o ID 4 não foi utilizado e a coluna Identity utilizou o ID com valor igual a 5.

Ainda utilizando o exemplo anterior, suponha a inserção de um novo cliente utilizando um contexto transacional e um ROLLBACK.

BEGIN TRANSACTION
INSERT INTO tblClientes (ClienteNome) VALUES ('Jaci')

-- Verificação do Identity
SELECT
    ClienteID, ClienteNome
FROM
    tblClientes

ROLLBACK

Nesse caso, após realizar o INSERT dentro de uma transação, é possível visualizar que o ID 6 foi utilizado, mas a transação foi revertida. Como o ID 6 não foi utilizado, é esperado que ele seja o próximo da lista.

BEGIN TRANSACTION
INSERT INTO tblClientes (ClienteNome) VALUES ('Jaci')
COMMIT

-- Verificação do Identity
SELECT
    ClienteID, ClienteNome
FROM
    tblClientes

Após abrir uma transação, realizar a inserção e finalizar a transação, a conferência mostra que o ID 7 foi utilizado ao invés do ID 6. Isso ocorre porque o ID 6 foi descartado na transação anterior.

Esses GAPs ocorrem porque, por motivos de eficiência. Assim que uma instrução INSERT é disparada, o Identity já é aproveitado independente do que ocorra. Mesmo que haja um DELETE ou um ROLLBACK, os valores de uma coluna Identity não podem ser reaproveitados e seguem para o próximo número da seqüência. Esse comportamento é em parte justificável, visto que um reaproveitamento dos seqüenciais em um ambiente de extrema concorrência poderia ser desatroso do ponto de vista de performance.