Me di cuenta de que cuando configura una replicación transaccional, SQL Server establecerá la administración del rango de identidad en manual. Lo que esto significa es que en mi base de datos de suscripción, cuando trato de insertar un nuevo registro en una tabla cuyo PK es una columna de identidad, me dará un error y dirá que intentó insertar un PK de "1", "2 "," 3 ", etc. Esto se debe a que el valor de identidad actual para todas las columnas de identidad en el suscriptor se restablece al valor inicial (generalmente 1) en lugar de permanecer en lo que estaba en el editor.
Entiendo por qué SQL Server hace esto: se supone que debes dejar la tabla de suscriptores como de solo lectura. Sin embargo, mi escenario es un poco poco ortodoxo: actualizo a mi suscriptor de vez en cuando a través de la replicación, hago una copia de seguridad inmediata de esa base de datos, luego quiero hacer algunas actualizaciones para el suscriptor que NO se enviarán al editor, luego cuando vuelvo a actualizar el suscriptor, restauro su base de datos de la copia de seguridad anterior y obtengo las últimas actualizaciones. Debido a que quiero hacer actualizaciones al suscriptor entre estas actualizaciones ('deltas temporales' si lo desea), necesito que la columna de identidad funcione y no se restablezca a 1 cuando se replica.
Intenté activar la administración automática del rango de identidad al configurar mi publicación, pero eso solo me da el siguiente error cuando intento agregar una tabla a la publicación:
Msg 21231, Nivel 16, Estado 1, Procedimiento sp_MSrepl_addarticle, Línea 2243
El soporte de rango de identidad automático es útil solo para publicaciones que permiten actualizar suscriptores.
¿Hay alguna forma de solucionar este problema? Quiero presentar esta replicación a SQL Server como si fuera de solo lectura al final del suscriptor porque no planeo hacer actualizaciones que serán enviadas de vuelta al editor , pero sí quiero hacer actualizaciones temporales que será borrado antes de la próxima replicación.
También he considerado que la replicación de instantáneas podría ser un método más apropiado que la replicación transaccional para mi patrón de uso, pero el problema es que la replicación de instantáneas requiere enviar toda la base de datos a cada actualización; Como estoy planeando realizar una copia de seguridad inmediata de la base de datos después de la última replicación, no debería necesitar hacer esa transferencia completa cada vez; solo los cambios desde la última vez.
Is there any way I can get round this problem?
Debe establecer la columna de identidad como NO PARA REPLICAR usando sys.sp_identitycolumnforreplication para sql server 2005 y versiones posteriores. Incluso no tiene que volver a capturar sus artículos cuando cambia la columna de identidad como no para la replicación. Simplemente no lo hagas usando GUI.Respuestas:
Suponiendo que su editor está utilizando una identidad int que comienza en 1, puede emitir
DBCC CHECKIDENT('dbo.mytable', RESEED, -2147483648)
en el suscriptor. Luego puede usar el rango de -2147483648 a 0 para mantener sus "deltas temporales".fuente
Lo que terminé haciendo fue mantener una replicación transaccional basada en extracción y hacer que mi programa actualizara los valores de identidad del suscriptor para que fueran los mismos que los de la base de datos de publicaciones inmediatamente después de la sincronización (algo que desearía que el agente de distribución hiciera por su propia cuenta ) En pseudocódigo se parecía un poco a esto:
Parece funcionar bien. El bit HACK se debe a que, aunque de forma predeterminada y con todas mis tablas, el valor de identidad solo se incrementa en uno, se puede configurar de manera diferente, por lo que técnicamente aquí debe averiguar cómo aumenta el valor de identidad en la tabla del editor e incrementarlo. mismo camino.
fuente
Mi método preferido para manejar esto es hacer lo siguiente:
a. Primero detenga su agente de replicación (para que no obtenga datos nuevos en su DB de suscriptor)
si. Segundo renombra tu tabla existente
C. Vuelva a crear su tabla con el conjunto IDENTITY
re. Rellene su tabla (desde [BackupTableName]) con SET IDENTITY_INSERT
Una vez que tenga la restricción IDENTITY en su base de datos, puede hacer una replicación personalizada (es decir, cambiar su proceso de inserción de respuesta a SET IDENTITY_INSERT [TableName] ON o puede establecer el indicador NOT FOR REPLICATION en la tabla (que le dice al servidor SQL que si el usuario que se conecta es el agente de replicación, espere que se suministre el valor de IDENTIDAD) ( prefiero el enfoque de replicación personalizado, ya que me da más flexibilidad )
mi. Modifique su procedimiento almacenado de replicación de inserción (generalmente denominado sp_MSins_CurrentTable) para insertar también utilizando
SET IDENTITY INSERT
F. Ahora puede reiniciar su agente de replicación.
fuente
DBCC CHECKIDENT
, este método es una gran cantidad de trabajo.