Percebi que, quando você configura uma replicação transacional, o SQL Server define o gerenciamento do intervalo de identidades como manual. O que isso significa é que, no meu banco de dados de inscrição, quando tento inserir um novo registro em uma tabela cuja PK é uma coluna de identidade, ele gera um erro e diz que tentou inserir uma PK de "1", "2 "," 3 "etc. etc. Isso ocorre porque o valor atual da identidade de todas as colunas de identidade no assinante é redefinido para o valor inicial (geralmente 1) em vez de permanecer no que era no editor.
Entendo por que o SQL Server faz isso - você deve deixar a tabela de assinantes como somente leitura. No entanto, meu cenário é um pouco ortodoxo - eu atualizo meu assinante periodicamente através da replicação, faço um backup imediato desse banco de dados e desejo fazer algumas atualizações no assinante que NÃO serão enviadas de volta ao editor e, em seguida, Quando vou atualizar o assinante novamente, restauro o banco de dados do backup anterior e retiro as atualizações mais recentes. Como desejo fazer atualizações para o assinante entre essas atualizações ('deltas temporários', se desejar), preciso que a coluna de identidade funcione e não redefina para 1 quando replicada.
Tentei ativar o gerenciamento automático de intervalo de identidades ao configurar minha publicação, mas isso só me dá o seguinte erro ao tentar adicionar uma tabela à publicação:
Msg 21231, Nível 16, Estado 1, Procedimento sp_MSrepl_addarticle, Linha 2243
O suporte automático ao intervalo de identidade é útil apenas para publicações que permitem a atualização de assinantes.
Existe alguma maneira de contornar esse problema? Eu quero apresentar essa replicação no SQL Server como se fosse somente leitura no final do assinante, porque não pretendo fazer atualizações que serão enviadas de volta ao editor , mas quero fazer atualizações temporárias que será apagado antes da próxima replicação.
Também considerei que a replicação de instantâneo pode ser um método mais apropriado do que a replicação transacional para o meu padrão de uso, mas o problema é que a replicação de instantâneo exige o envio de todo o maldito banco de dados a cada atualização; porque estou planejando fazer um backup imediato do banco de dados após a última replicação, não preciso fazer essa transferência toda vez; apenas as mudanças desde a última vez.
Is there any way I can get round this problem?
Você deve definir a coluna de identidade como NÃO PARA REPLICAÇÃO usando sys.sp_identitycolumnforreplication para sql server 2005 e versões posteriores . Você nem precisa refazer uma captura instantânea de seus artigos quando altera a coluna de identidade para não ser replicada. Apenas não faça isso usando GUI.Respostas:
Supondo que seu Publicador esteja usando uma identidade int que começa em 1, você pode emitir
DBCC CHECKIDENT('dbo.mytable', RESEED, -2147483648)
o assinante. Você pode usar o intervalo de -2147483648 a 0 para manter seus "deltas temporários".fonte
O que acabei fazendo foi ficar com uma replicação transacional baseada em pull e fazer com que meu programa atualizasse os valores de identidade do assinante para serem os mesmos do banco de dados de publicação imediatamente após a sincronização (meio que eu gostaria que o agente de distribuição fizesse por conta própria ) No pseudo-código, parecia um pouco com isso:
Parece funcionar bem. O bit HACK é porque, embora por padrão e com todas as minhas tabelas, o valor da identidade apenas aumente em uma, ele pode ser configurado de maneira diferente; portanto, aqui tecnicamente você deve descobrir como o valor da identidade é incrementado na tabela do editor e incrementado o mesma maneira.
fonte
Meu método preferido para lidar com isso é fazer o seguinte:
uma. Primeiro, pare o agente de replicação (para não receber novos dados no banco de dados do assinante)
b. Segundo renomeie sua tabela existente
c. Recrie sua tabela com o conjunto de IDENTITY
d. Preencha sua tabela (a partir de [BackupTableName]) com SET IDENTITY_INSERT
Depois de ter a restrição IDENTITY no seu banco de dados, você pode fazer a replicação personalizada (por exemplo: alterar o processo de inserção de inserção para SET IDENTITY_INSERT [TableName] ON ou definir o sinalizador NOT FOR REPLICATION na tabela (que informa ao SQL Server que se o usuário que está se conectando for o agente de replicação, espere que o valor de IDENTITY seja fornecido) ( prefiro a abordagem de replicação personalizada, pois ela me oferece mais flexibilidade )
e Modifique o procedimento armazenado de replicação de inserção (geralmente chamado sp_MSins_CurrentTable) para também inserir usando
SET IDENTITY INSERT
f. Agora você pode reiniciar seu agente de replicação.
fonte
DBCC CHECKIDENT
, esse método é uma quantidade enorme de trabalho.