Ich habe festgestellt, dass SQL Server beim Einrichten einer Transaktionsreplikation die Verwaltung des Identitätsbereichs auf manuell setzt. Dies bedeutet, dass in meiner Abonnementdatenbank beim Versuch, einen neuen Datensatz in eine Tabelle einzufügen, deren PK eine Identitätsspalte ist, eine Fehlermeldung angezeigt wird und angegeben wird, dass versucht wurde, eine PK von "1", "2" einzufügen "," 3 "usw. Dies liegt daran, dass der aktuelle Identitätswert für alle Identitätsspalten auf dem Abonnenten auf den Startwert (normalerweise 1) zurückgesetzt wird, anstatt auf dem Stand des Herausgebers zu bleiben.
Ich verstehe, warum SQL Server dies tut - Sie sollten die Abonnententabelle schreibgeschützt lassen. Mein Szenario ist jedoch etwas unorthodox - ich aktualisiere meinen Abonnenten von Zeit zu Zeit durch Replikation, mache eine sofortige Sicherung dieser Datenbank und möchte dann einige Aktualisierungen für den Abonnenten vornehmen, die dann NICHT an den Herausgeber zurückgeschickt werden Wenn ich den Abonnenten erneut aktualisiere, stelle ich seine Datenbank aus der früheren Sicherung wieder her und rufe die neuesten Updates ab. Da ich zwischen diesen Aktualisierungen Aktualisierungen für den Abonnenten durchführen möchte (wenn Sie so wollen, "temporäre Deltas"), muss die Identitätsspalte funktionieren und beim Replizieren nicht auf 1 zurückgesetzt werden.
Ich habe versucht, die automatische Verwaltung des Identitätsbereichs beim Einrichten meiner Publikation zu aktivieren. Dabei wird jedoch nur der folgende Fehler angezeigt, wenn ich versuche, der Publikation eine Tabelle hinzuzufügen:
Meldung 21231, Ebene 16, Status 1, Prozedur sp_MSrepl_addarticle, Zeile 2243 Die
automatische Unterstützung des Identitätsbereichs ist nur für Veröffentlichungen nützlich, in denen Abonnenten aktualisiert werden können.
Gibt es eine Möglichkeit, dieses Problem zu umgehen? Ich möchte diese Replikation SQL Server so präsentieren, als wäre sie auf Abonnentenseite schreibgeschützt, da ich nicht vorhabe, Aktualisierungen vorzunehmen , die an den Herausgeber zurückgesendet werden , aber ich möchte vorübergehende Aktualisierungen vornehmen wird vor der nächsten Replikation gelöscht.
Ich habe auch in Betracht gezogen, dass die Snapshot-Replikation für mein Verwendungsmuster eine geeignetere Methode als die Transaktionsreplikation sein könnte, aber das Problem ist, dass bei der Snapshot-Replikation bei jedem einzelnen Update die gesamte verdammte Datenbank gesendet werden muss. Da ich vorhabe, nach der letzten Replikation sofort eine Sicherungskopie der Datenbank zu erstellen, sollte ich nicht jedes Mal die gesamte Übertragung durchführen müssen. nur die Änderungen seit dem letzten Mal.
Is there any way I can get round this problem?
Sie müssen die Identitätsspalte mit sys.sp_identitycolumnforreplication für SQL Server 2005 und höher als NOT FOR REPLICATION festlegen . Sie müssen Ihre Artikel nicht einmal erneut aufnehmen, wenn Sie die Identitätsspalte als nicht für die Replikation ändern. Mach es einfach nicht mit der GUI.Antworten:
Angenommen, Ihr Publisher verwendet eine int-Identität, die bei 1 beginnt, können Sie dies
DBCC CHECKIDENT('dbo.mytable', RESEED, -2147483648)
beim Abonnenten ausstellen . Sie können dann den Bereich von -2147483648 bis 0 verwenden, um Ihre "temporären Deltas" zu speichern.quelle
Am Ende blieb ich bei einer Pull-basierten Transaktionsreplikation und ließ mein Programm die Abonnentenidentitätswerte so aktualisieren, dass sie unmittelbar nach der Synchronisierung mit denen in der Veröffentlichungsdatenbank übereinstimmen (so wie ich es mir wünschte, dass der Distributionsagent von sich aus tat ). Im Pseudocode sah es ein bisschen so aus:
Scheint in Ordnung zu funktionieren. Das HACK-Bit ist darauf zurückzuführen, dass der Identitätswert standardmäßig und bei allen meinen Tabellen nur um eins erhöht wird. Er kann jedoch unterschiedlich konfiguriert werden. Technisch gesehen sollten Sie hier herausfinden, wie der Identitätswert in der Herausgebertabelle inkrementiert wird, und ihn erhöhen gleicher Weg.
quelle
Meine bevorzugte Methode, um damit umzugehen, ist Folgendes:
ein. Stoppen Sie zuerst Ihren Replikationsagenten (damit Sie keine neuen Daten in Ihre Abonnenten-Datenbank erhalten).
b. Zweitens benennen Sie Ihre vorhandene Tabelle um
c. Erstellen Sie Ihre Tabelle mit festgelegtem IDENTITY neu
d. Füllen Sie Ihre Tabelle (aus dem [BackupTableName]) mit SET IDENTITY_INSERT
Sobald Sie die IDENTITY- Einschränkung für Ihre Datenbank haben , können Sie entweder eine benutzerdefinierte Replikation durchführen (dh Ihren Insert-Repl-Prozess in SET IDENTITY_INSERT [TableName] ON ändern oder das NOT NOT REPLICATION-Flag für die Tabelle setzen (das SQL Server dies mitteilt) Wenn der verbindende Benutzer der Replikationsagent ist, erwarten Sie, dass der IDENTITY-Wert angegeben wird. ( Ich bevorzuge den benutzerdefinierten Replikationsansatz, da er mir mehr Flexibilität bietet. )
e. Ändern Sie die gespeicherte Prozedur zum Einfügen der Replikation (normalerweise sp_MSins_CurrentTable), um sie auch mit einzufügen
SET IDENTITY INSERT
f. Jetzt können Sie Ihren Replikationsagenten neu starten.
quelle
DBCC CHECKIDENT
ist diese Methode eine enorme Menge an Arbeit.