Saya perhatikan bahwa ketika Anda mengatur replikasi transaksional, SQL Server akan mengatur manajemen rentang identitas ke manual. Apakah ini berarti bahwa dalam database berlangganan saya, ketika saya mencoba untuk memasukkan catatan baru ke dalam tabel yang PK-nya adalah kolom identitas, itu akan memberi saya kesalahan dan mengatakan bahwa ia mencoba memasukkan PK "1", "2 "," 3 ", dll. Ini karena nilai identitas saat ini untuk semua kolom identitas pada pelanggan akan diatur ulang ke nilai awal (biasanya 1) alih-alih tetap seperti pada penerbit.
Saya mengerti mengapa SQL Server melakukan ini - Anda seharusnya membiarkan tabel pelanggan sebagai read-only. Namun, skenario saya sedikit tidak lazim - saya memperbarui pelanggan saya dari waktu ke waktu melalui replikasi, membuat cadangan langsung dari DB itu, maka saya ingin melakukan beberapa pembaruan kepada pelanggan bahwa TIDAK AKAN didorong kembali ke penerbit, lalu ketika saya pergi untuk memperbarui pelanggan lagi, saya mengembalikan databasenya dari cadangan sebelumnya dan menarik pembaruan terbaru. Karena saya ingin melakukan pembaruan untuk pelanggan di antara pembaruan ini ('sementara delta' jika Anda mau), saya perlu kolom identitas untuk bekerja dan tidak mengatur ulang ke 1 ketika direplikasi.
Saya mencoba mengaktifkan manajemen rentang identitas otomatis saat menyiapkan publikasi saya, tetapi itu hanya memberi saya kesalahan berikut ketika saya mencoba menambahkan tabel ke publikasi:
Msg 21231, Level 16, Negara Bagian 1, Prosedur sp_MSrepl_addarticle, Baris 2243
Dukungan rentang identitas otomatis hanya berguna untuk publikasi yang memperbolehkan memperbarui pelanggan.
Apakah ada cara saya bisa mengatasi masalah ini? Saya memang ingin menyajikan replikasi ini ke SQL Server seolah-olah hanya-baca di akhir pelanggan karena saya tidak berencana membuat pembaruan yang akan didorong kembali ke penerbit , tetapi saya ingin membuat pembaruan sementara yang akan dihapus sebelum replikasi berikutnya.
Saya juga telah mempertimbangkan bahwa replikasi snapshot mungkin merupakan metode yang lebih tepat daripada replikasi transaksional untuk pola penggunaan saya, tetapi masalahnya adalah replikasi snapshot memerlukan pengiriman seluruh DB setiap pembaruan tunggal; karena saya berencana mengambil cadangan langsung DB setelah replikasi terbaru, saya tidak perlu melakukan seluruh transfer setiap waktu; hanya perubahan sejak terakhir kali.
Is there any way I can get round this problem?
Anda harus mengatur kolom identitas sebagai BUKAN UNTUK REPLIKASI menggunakan sys.sp_identitycolumnforreplication untuk sql server 2005 dan lebih tinggi. Anda bahkan tidak perlu mengulang artikel Anda ketika Anda mengubah kolom identitas bukan untuk replikasi. Jangan lakukan itu menggunakan GUI.Jawaban:
Dengan asumsi Penerbit Anda menggunakan identitas int yang dimulai pada 1, Anda bisa mengeluarkan
DBCC CHECKIDENT('dbo.mytable', RESEED, -2147483648)
pada pelanggan. Anda kemudian dapat menggunakan rentang dari -2147483648 hingga 0 untuk menahan "delta sementara" Anda.sumber
Apa yang akhirnya saya lakukan adalah tetap dengan replikasi transaksional berbasis tarik, dan memiliki program saya memperbarui nilai-nilai identitas pelanggan menjadi sama dengan yang ada di database publikasi segera setelah sinkronisasi (agak apa yang saya berharap agen distribusi lakukan dengan kemauan sendiri ). Dalam pseudo-code tampilannya sedikit seperti ini:
Tampaknya bekerja dengan baik. Bit HACK adalah karena, meskipun secara default dan dengan semua tabel saya, nilai identitas hanya bertambah satu, itu dapat dikonfigurasi secara berbeda, jadi secara teknis di sini Anda harus mencari tahu bagaimana nilai identitas meningkat pada tabel penerbit dan menambahkannya pada cara yang sama.
sumber
Metode pilihan saya untuk menangani ini adalah dengan melakukan hal berikut:
Sebuah. Pertama-tama hentikan agen replikasi Anda (jadi Anda tidak mendapatkan data baru ke dalam DB pelanggan Anda)
b. Ubah nama kedua tabel yang ada
c. Buat kembali meja Anda dengan set IDENTITY
d. Isi ulang meja Anda (dari [BackupTableName]) dengan SET IDENTITY_INSERT
Setelah Anda memiliki batasan IDENTITY pada DB Anda, maka Anda dapat melakukan replikasi khusus (yaitu: mengubah proc pengadaan sisipkan Anda ke SET IDENTITY_INSERT [TableName] ON atau Anda dapat mengatur tanda NOT FOR REPLICATION di atas meja (yang memberi tahu SQL server bahwa jika pengguna yang terhubung adalah agen replikasi, harap nilai IDENTITAS diberikan ( saya lebih suka pendekatan replikasi khusus, karena memberikan saya lebih banyak fleksibilitas )
e. Ubah prosedur penyisipan replikasi tersimpan Anda (biasanya bernama sp_MSins_CurrentTable) untuk juga menyisipkan menggunakan
SET IDENTITY INSERT
f. Sekarang Anda dapat memulai kembali agen replikasi Anda.
sumber
DBCC CHECKIDENT
, metode ini sangat banyak pekerjaan.