Zauważyłem, że po skonfigurowaniu replikacji transakcyjnej SQL Server ustawi zarządzanie zakresem tożsamości na ręczne. Oznacza to, że w mojej bazie danych subskrypcji, gdy próbuję wstawić nowy rekord do tabeli, której PK jest kolumną tożsamości, da mi błąd i powie, że próbował wstawić PK „1”, „2 ”,„ 3 ”itd. Jest tak, ponieważ bieżąca wartość tożsamości dla wszystkich kolumn tożsamości subskrybenta zostaje zresetowana do wartości początkowej (zwykle 1) zamiast pozostawania na poziomie, w jakim była u wydawcy.
Rozumiem, dlaczego SQL Server to robi - powinieneś zostawić tabelę subskrybentów jako tylko do odczytu. Jednak mój scenariusz jest trochę niekonwencjonalny - od czasu do czasu aktualizuję subskrybenta poprzez replikację, tworzę natychmiastową kopię zapasową tej bazy danych, a następnie chcę dokonać aktualizacji subskrybenta, aby NIE ZOSTAŁ przekazany do wydawcy, a następnie kiedy idę, aby ponownie zaktualizować subskrybenta, przywracam jego bazę danych z wcześniejszej kopii zapasowej i ściągam najnowsze aktualizacje. Ponieważ chcę robić aktualizacje subskrybentowi między tymi aktualizacjami („tymczasowe delty”, jeśli chcesz), potrzebuję kolumny tożsamości do działania i nie resetuję do 1 po replikacji.
Próbowałem włączyć automatyczne zarządzanie zakresem tożsamości podczas konfigurowania mojej publikacji, ale to daje mi następujący błąd podczas próby dodania tabeli do publikacji:
Msg 21231, poziom 16, stan 1, procedura sp_MSrepl_addarticle, wiersz 2243 Obsługa
automatycznego zakresu tożsamości jest przydatna tylko w publikacjach, które umożliwiają aktualizowanie subskrybentów.
Czy jest jakiś sposób na obejście tego problemu? W pewnym sensie chcę przedstawić tę replikę SQL Serverowi, tak jakby była ona tylko do odczytu po stronie subskrybenta, ponieważ nie planuję aktualizacji, które zostaną przekazane z powrotem do wydawcy , ale chcę wprowadzić tymczasowe aktualizacje, które zostaną usunięte przed następną replikacją.
Rozważyłem również, że replikacja migawek może być bardziej odpowiednią metodą niż replikacja transakcyjna dla mojego wzorca użytkowania, ale problem polega na tym, że replikacja migawki wymaga wysyłania całego darn DB przy każdej aktualizacji; ponieważ planuję wykonać natychmiastową kopię zapasową bazy danych po najnowszej replikacji, nie powinienem za każdym razem robić tego całego transferu; tylko zmiany od ostatniego razu.
Is there any way I can get round this problem?
Musisz ustawić kolumnę tożsamości jako NIE DO REPLIKACJI za pomocą sys.sp_identitycolumnforreplication dla serwera SQL 2005 i nowszych . Nie musisz nawet ponownie fotografować artykułów, gdy zmienisz kolumnę tożsamości, ponieważ nie do replikacji. Po prostu nie rób tego za pomocą GUI.Odpowiedzi:
Zakładając, że wydawca używa tożsamości int, która zaczyna się od 1, możesz wydać
DBCC CHECKIDENT('dbo.mytable', RESEED, -2147483648)
subskrybentowi. Następnie możesz użyć zakresu od -2147483648 do 0, aby zatrzymać „tymczasowe delty”.źródło
Skończyło się na tym, że trzymałem się replikacji transakcyjnej opartej na ściąganiu i kazałem mojemu programowi aktualizować wartości tożsamości subskrybenta, aby były takie same jak te w bazie danych publikacji natychmiast po synchronizacji (co chciałbym, żeby agent dystrybucyjny zrobił z własnej woli ). W pseudokodzie wyglądało to trochę tak:
Wydaje się działać OK. Bit HACK polega na tym, że chociaż domyślnie i we wszystkich moich tabelach wartość tożsamości zwiększa się tylko o jeden, można ją skonfigurować inaczej, więc technicznie tutaj powinieneś dowiedzieć się, w jaki sposób wartość tożsamości zwiększa się w tabeli wydawcy i zwiększa ją ta sama droga.
źródło
Moją preferowaną metodą radzenia sobie z tym jest:
za. Najpierw zatrzymaj agenta replikacji (aby nie wprowadzać żadnych nowych danych do bazy danych subskrybenta)
b. Po drugie zmień nazwę istniejącej tabeli
do. Stwórz ponownie swój stół z zestawem IDENTITY
re. Wypełnij tabelę (z [BackupTableName]) za pomocą SET IDENTITY_INSERT
Po wprowadzeniu ograniczenia tożsamości na bazie danych można wykonać niestandardową replikację (np .: zmienić proces wstawiania repl insert na SET IDENTITY_INSERT [nazwa_tabeli] WŁĄCZONY lub ustawić flagę NOT FOR REPLICATION na tabeli (która informuje serwer SQL, że jeśli użytkownik łączący się jest agentem replikacji, należy spodziewać się podania wartości TOŻSAMOŚCI) ( wolę niestandardowe podejście do replikacji, ponieważ daje mi to większą elastyczność )
mi. Zmodyfikuj procedurę składowaną replikacji wstawiania (zwykle o nazwie sp_MSins_CurrentTable), aby również wstawić za pomocą
SET IDENTITY INSERT
fa. Teraz możesz zrestartować agenta replikacji.
źródło
DBCC CHECKIDENT
, ta metoda to ogromna ilość pracy.