লেনদেনের প্রতিরূপ জন্য পরিচয় ব্যাপ্তি সঙ্গে লেনদেন


9

আমি লক্ষ্য করেছি যে আপনি যখন কোনও লেনদেনের প্রতিরূপ সেট আপ করবেন তখন এসকিউএল সার্ভার ম্যানুয়ালটিতে পরিচয় পরিসীমা পরিচালনা সেট করবে। এর অর্থ হ'ল আমার সাবস্ক্রিপশন ডেটাবেজে, যখন আমি কোনও টেবিলে একটি নতুন রেকর্ড সন্নিবেশ করানোর চেষ্টা করি যার পিকে একটি পরিচয় কলাম হয়, এটি আমাকে ত্রুটি দেবে এবং বলবে যে এটি "1", "2 এর কোনও পিকে sertোকানোর চেষ্টা করেছিল? "," 3 "ইত্যাদি এটি কারণ গ্রাহকের সমস্ত পরিচয় কলামের বর্তমান পরিচয় মানটি প্রকাশকের উপরে থাকায় পরিবর্তে বীজ মানের (সাধারণত 1) পুনরায় সেট হয়ে যায়।

এসকিউএল সার্ভার কেন এটি করে তা আমি বুঝতে পেরেছি - আপনার গ্রাহক টেবিলটি কেবল পঠনযোগ্য হিসাবে ছেড়ে দেওয়ার কথা। যাইহোক, আমার পরিস্থিতিটি কিছুটা অপ্রচলিত - আমি আমার গ্রাহককে সময়ে সময়ে প্রতিলিপি দ্বারা আপডেট করি, সেই ডিবিটির তাত্ক্ষণিক ব্যাকআপ করি, তারপরে আমি গ্রাহককে কিছু আপডেট করতে চাই যা প্রকাশকের কাছে ফিরে যেতে হবে না, তারপরে যখন আমি আবার গ্রাহক আপডেট করতে যাই, আমি পূর্বের ব্যাকআপ থেকে এটির ডাটাবেসটি পুনরুদ্ধার করি এবং সর্বশেষ আপডেটগুলি টানছি। যেহেতু আমি এই আপডেটগুলির মধ্যে গ্রাহককে আপডেট করতে চাই ('যদি আপনি চান তবে' অস্থায়ী ডেল্টাস '), কাজ করার জন্য আমার পরিচয় কলাম দরকার এবং প্রতিলিপি করাতে 1 এ পুনরায় সেট করার দরকার নেই।

আমি আমার প্রকাশনার সেট আপ করার সময় স্বয়ংক্রিয় পরিচয় পরিসর পরিচালনা চালু করার চেষ্টা করেছি, তবে যখন আমি প্রকাশনায় একটি সারণী যুক্ত করার চেষ্টা করি তখন তা আমাকে নিম্নলিখিত ত্রুটি দেয়:

এমএসজি 21231, স্তর 16, রাজ্য 1, পদ্ধতি sp_MSrepl_addarticle, লাইন 2243
স্বয়ংক্রিয় পরিচয় পরিসীমা সমর্থন কেবলমাত্র প্রকাশনাগুলির জন্য দরকারী যা গ্রাহকদের আপডেট করার অনুমতি দেয়।

এই সমস্যাটি আমি কীভাবে পেতে পারি? আমি এসকিউএল সার্ভারের কাছে এই প্রতিলিপিটি এমনভাবে উপস্থাপন করতে চাই যা এটি কেবল গ্রাহক প্রান্তে কেবল পঠনযোগ্য ছিল কারণ আমি আপডেটগুলি তৈরির পরিকল্পনা করি না যা প্রকাশকের কাছে ফিরে যায় , তবে আমি অস্থায়ী আপডেট করতে চাই যা পরবর্তী প্রতিরূপের আগে মুছে ফেলা হবে।

আমি এও বিবেচনা করেছি যে স্ন্যাপশটের প্রতিলিপিটি আমার ব্যবহারের প্যাটার্নের জন্য লেনদেনের অনুলিপিকরণের চেয়ে আরও উপযুক্ত পদ্ধতি হতে পারে তবে সমস্যাটি হ'ল স্ন্যাপশটের প্রতিলিপিটির প্রতিটি একক আপডেটে পুরো ডার্ন ডিবি প্রেরণ করা প্রয়োজন ; যেহেতু আমি সর্বশেষ প্রতিলিপি পরে ডিবি-এর তাত্ক্ষণিক ব্যাকআপ নেওয়ার পরিকল্পনা করছি, প্রতিবার আমার পুরো ট্রান্সফার করার দরকার নেই; গতবারের থেকে কেবল পরিবর্তনগুলি।


আপনি এসকিউএল সার্ভারের কোন সংস্করণ ব্যবহার করছেন? আপনি কি টেবিলটির নতুন সংজ্ঞা দিতে পারেন?

2008 r2। আমি দেখতে পাচ্ছি না যে টেবিলটির পুনরায় সংজ্ঞা দেওয়া কীভাবে এই সমস্যার সমাধান করবে ...
Jez

আমি সিকোয়েন্স ব্যবহার করে একটি সমাধানের কথা ভাবছিলাম, তবে এটি কেবল এসকিউএল 2012 এর জন্য

2
Is there any way I can get round this problem?২০০q এবং তার বেশি বেকার সার্ভারের জন্য sys.sp_identitycolumnforreplication ব্যবহার করে আপনাকে পরিচয় কলাম সেট করতে হবে না । এমনকি আপনি যখন নিজের পরিচয় কলামটি প্রতিলিপি হিসাবে পরিবর্তন করবেন না তখন আপনার নিবন্ধগুলি পুনরায় ফটোশট করতে হবে না। জিইআইআই ব্যবহার করে এটি করবেন না।
কিন শাহ

এটি ইতিমধ্যে প্রতিলিপি জন্য চিহ্নিত করা হয়েছে। এটিই মূলত সমস্যা - এসকিউএল সার্ভার গ্রাহক হিসাবে পরিচয় সম্পর্কিত তথ্যটি অনুলিপি করে না, এটি 1 থেকে শুরু হবে
জেজ

উত্তর:


3

আপনার প্রকাশক 1 টি থেকে শুরু হওয়া কোনও int পরিচয় ব্যবহার করছেন বলে ধরে নেওয়া, আপনি DBCC CHECKIDENT('dbo.mytable', RESEED, -2147483648) গ্রাহককে ইস্যু করতে পারেন । তারপরে আপনি আপনার "অস্থায়ী ডেল্টাস" ধরে রাখতে -2147483648 থেকে 0 অবধি ব্যবহার করতে পারেন।


এই সমাধানটি আমি নিয়ে এসেছি, তবে এর অর্থ হল আমার কোডটি প্রকাশক এবং গ্রাহকের সাথে সংযুক্ত হচ্ছে এবং পরিচয়গুলি ম্যানুয়ালি সিঙ্ক্রোনাইজ করছে। আমি আশা করছি এটি করার আরও একটি স্বয়ংক্রিয় উপায় আছে।
জেজ

আপনার নিজের পরিচয় ম্যানুয়ালি সিঙ্ক্রোনাইজ করার দরকার কী? কেবলমাত্র গ্রাহককে একটি সঞ্চিত পদ্ধতি লিখুন যা প্রতিটি টেবিলের জন্য চেকসিডেন্ট চালায় যা আপনি অস্থায়ী বদ্বীপে সংরক্ষণ করছেন এবং স্ন্যাপশট প্রয়োগ শেষ হওয়ার পরে এটি চালান। বিতরণ এজেন্টগুলি "আসল" পরিচয়ের ব্যাপ্তিতে ঘটে যাওয়ার সাথে সাথে পরিবর্তনগুলি সন্নিবেশ করবে এবং সরাসরি গ্রাহকের সাথে করা পরিবর্তনগুলি নেতিবাচক সীমার মধ্যে থাকবে।
লিয়াম কনফ্রে

1

আমি যা করে শেষ করেছি তা টান-ভিত্তিক লেনদেনের অনুলিপি সহকারে আঁকড়ানো ছিল এবং আমার প্রোগ্রামটি গ্রাহক পরিচয় মানগুলি সিঙ্ক্রোনাইজেশনের অবিলম্বে প্রকাশের ডেটাবেজে থাকা সমান হওয়ার জন্য আপডেট করেছে (প্রযোজনা বিতরণকারী এজেন্টটি নিজের ইচ্ছামত কাজটি করতে চাই )। সিউডো-কোডে এটি দেখতে কিছুটা এ জাতীয় দেখাচ্ছে:

synchronize databases with TransSynchronizationAgent

equivalentTablesNotFound is a list of strings
for each table in publisher tables:
    try:
        check table identity value (this is via functionality provided by .NET's Microsoft.SqlServer.Management.Smo.Server class)
        parse identity value as integer to newIdentity
        if the table's identity value was NULL, skip to next loop iteration
        (HACK) increment newIdentity value by 1
        if there is no subscriber table with the same name as this one:
            record its name in equivalentTablesNotFound and skip to next loop iteration
        set subscriber table with same name's identity value to newIdentity using TSQL: DBCC CHECKIDENT ("tableName", newIdentity)
    catch:
        if exception shows that the error was because the table doesn't have an identity column, drop the exception

if equivalentTablesNotFound has more than zero entries, warn about tables on publisher without an equivalent name on subscriber

ঠিক আছে কাজ মনে হচ্ছে। হ্যাক বিটটি হ'ল, যদিও ডিফল্টরূপে এবং আমার সমস্ত টেবিলের সাথে পরিচয় মানটি একে একে বাড়িয়ে দেয়, এটি আলাদাভাবে কনফিগার করা যায়, সুতরাং প্রযুক্তিগতভাবে এখানে আপনাকে প্রকাশক টেবিলে কীভাবে পরিচয় মান বাড়বে এবং এটি বৃদ্ধি করবে তা খুঁজে বের করা উচিত একই ভাবে.


0

এটি পরিচালনা করার জন্য আমার পছন্দসই পদ্ধতিটি হ'ল নিম্নলিখিতটি করা:

ক। প্রথমে আপনার প্রতিলিপি এজেন্ট বন্ধ করুন (যাতে আপনি আপনার গ্রাহক ডিবিতে কোনও নতুন ডেটা পাচ্ছেন না)

খ। দ্বিতীয়টি আপনার বিদ্যমান টেবিলটির নতুন নাম দিন

exec sp_rename '[CurrentTable]', '[BackupTableName]'

গ। পরিচয় সেট সহ আপনার টেবিলটি পুনরায় তৈরি করুন

CREATE TABLE [CurrentTable]
(
   ID INT NOT NULL IDENTITY(1,1), 
   OtherField VARCHAR(10) NULL,
   ....
)

ঘ। আপনার টেবিলটি ব্যাকফিল করুন ([ব্যাকআপটিবল নামটি থেকে) এসইডি আইডিএনটিটিআইপিএসআরটি দিয়ে

SET IDENTITY_INSERT [CurrentTable] ON
INSERT INTO [CurrentTable] (ID, OtherField, ...)
SELECT ID, OtherField, ....
FROM [BackupTableName]
SET IDENTITY_INSERT [CurrentTable] OFF

একবার আপনি আছে পরিচয়কে আপনার ডিবি উপর বাধ্যতা, তাহলে আপনি পারেন কাস্টম রেপ্লিকেশন করতে পারি না (অর্থাৎ, সেট IDENTITY_INSERT [tablename] চালু করার জন্য আপনার সন্নিবেশ repl proc পরিবর্তন বা আপনি টেবিলের উপর আত্ম পতাকা (যা SQL সার্ভার যে বলে না সেট করতে পারেন যদি সংযোগকারী ব্যবহারকারী প্রতিলিপি এজেন্ট হন তবে পরিচয় মানটি সরবরাহ করা হবে আশা করুন) ( আমি কাস্টম প্রতিলিপি পদ্ধতির পছন্দ করি, কারণ এটি আমাকে আরও নমনীয়তা দেয় )

ঙ। ব্যবহার করে sertোকাতে আপনার সন্নিবেশ প্রতিলিপি সঞ্চিত পদ্ধতি (সাধারণত নামযুক্ত sp_MSins_CurrentTable) পরিবর্তন করুনSET IDENTITY INSERT

ALTER procedure [dbo].[sp_MSins_CurrentTable]
    @c1 int, @c2 varchar(50), ...
as
begin
    /* allow replication to insert values for IDENTITY */
    SET IDENTITY_INSERT [CurrentTable] ON
    insert into [CurrentTable]
        ([ID], [OtherField], ...)
    values
        (@c1, @c2, ...)
    /* now turn off Identity insert */
    SET IDENTITY_INSERT [CurrentTable] OFF
end

চ। এখন আপনি আপনার প্রতিলিপি এজেন্ট পুনরায় চালু করতে পারেন।


1
LOL, ব্যবহারের তুলনায় DBCC CHECKIDENT, এই পদ্ধতিটি কাজের একটি বিশাল পরিমাণ।
জেজ

@ জিজ আপনাকে ডিবিসিসি চেকিডেন্ট চালানোর জন্য টেবিলটি পুনরায় তৈরি করতে হবে ... প্রতিরূপের একটি স্ন্যাপশট পরিচয় সীমাবদ্ধতার সাথে টেবিলটি তৈরি করবে (আপনার q এর উপর ভিত্তি করে আমি বলব যে ডিবিসিসি চেকিডেন্ট জিতেছে 't work)
অ্যান্ড্রু বিকার্টন

এফওয়াইআই এটি কাজ করেছিল এবং প্রতিলিপি পরিচয় সীমাবদ্ধতার সাথে টেবিল তৈরি করে ...
জেজ

@ জিজ আপনি কোন ধরণের প্রতিলিপি সেটআপ করেছেন? (যদি আপনি এটি মার্জ হিসাবে সেট করেন তবে এটি ঘটবে, সাধারণত এটি হয় না, যদিও আপনি জিইআইআই ব্যবহার না করেন তবে প্রতিলিপিটি অত্যন্ত স্বনির্ধারিত হয়)
অ্যান্ড্রু বিকারটন

লেনদেনগত। যেমনটি আমি বলেছি পরিচয় আছে, তবে বর্তমান পরিচয় মানটি বীজের মানটিতে পুনরায় সেট করা হয়েছে (1)।
জেজ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.