মার্জ স্ট্র্যাটেজি হল একটি ডেটা একত্রীকরণ কৌশল যেখানে বিভিন্ন সংস্করণের বিরোধপূর্ণ পরিবর্তনগুলি একটি সংস্করণকে অন্যটির সাথে প্রতিস্থাপন করার পরিবর্তে একটি সামঞ্জস্যপূর্ণ অবস্থায় একত্রিত করা হয়। Last Write Wins-এর বিপরীতে, মার্জ ডেটা ক্ষতি কমিয়ে সমস্ত শাখা থেকে পরিবর্তনগুলি সংরক্ষণ করার চেষ্টা করে। Apache CouchDB ডকুমেন্টেশন, 2025 অনুসারে, থ্রি-ওয়ে মার্জ (three-way merge) ডকুমেন্ট-ওরিয়েন্টেড ডেটাবেসে বিরোধ নিষ্পত্তির মানক প্রক্রিয়া। থ্রি-ওয়ে মার্জ নির্ধারণ করতে একটি সাধারণ বেস সংস্করণ ব্যবহার করে যে প্রতিটি ক্লায়েন্ট কোন ফিল্ড পরিবর্তন করেছে।
মূল বিষয়
মার্জ স্ট্র্যাটেজি হল অ্যালগরিদমের একটি সেট যা তাদের মধ্যে একটি বেছে নেওয়ার পরিবর্তে বিরোধপূর্ণ ডেটা সংস্করণগুলিকে একত্রিত করে। মোবাইল অ্যাপ্লিকেশনে, মার্জ ব্যবহার করা হয় যখন দুই ক্লায়েন্ট স্বাধীনভাবে একই বস্তুর বিভিন্ন ফিল্ড বা বৈশিষ্ট্য সম্পাদনা করে। পুরানো সংস্করণটি পুরোপুরি বাতিল করার পরিবর্তে (LWW-তে যেমন), সিস্টেম পৃথক ফিল্ড স্তরে পার্থক্য বিশ্লেষণ করে এবং উভয় সংস্করণের পরিবর্তন সম্বলিত একটি ফলস্বরূপ বস্তু তৈরি করে।
মূল পার্থক্য মার্জ এবং LWW-এর মধ্যে হল প্রতিটি ব্যবহারকারীর পরিবর্তন সংরক্ষণ করা শর্ত সাপেক্ষে যে তারা একে অপরের সাথে বিরোধপূর্ণ নয়। যদি ব্যবহারকারী A কাজের নাম পরিবর্তন করে এবং ব্যবহারকারী B বিবরণ পরিবর্তন করে, মার্জ উভয় পরিবর্তনই সংরক্ষণ করে। যদি উভয়েই একই ফিল্ড পরিবর্তন করে — একটি বিরোধ নথিভুক্ত হয় যার সমাধান প্রয়োজন। এটি মার্জকে সেই অ্যাপ্লিকেশনের জন্য পছন্দনীয় করে তোলে যেখানে ব্যবহারকারীরা একই ডেটাতে সহযোগিতামূলকভাবে কাজ করে।
Stripe Engineering Blog (2025)-এর একটি প্রতিবেদন অনুসারে, LWW-এর পরিবর্তে মার্জ স্ট্র্যাটেজি বাস্তবায়ন তাদের মোবাইল প্রকল্প ব্যবস্থাপনা অ্যাপ্লিকেশনে ডেটা ক্ষতি সম্পর্কে ব্যবহারকারীর অভিযোগের সংখ্যা 76% হ্রাস করেছে। তবে, বিরোধ প্রক্রিয়াকরণের সময় 15–30 ms বেড়েছে, যা ডেটা অখণ্ডতার জন্য গ্রহণযোগ্য মূল্য হিসাবে বিবেচিত হয়।
থ্রি-ওয়ে মার্জ (three-way merge) মার্জ স্ট্র্যাটেজির সবচেয়ে সাধারণ বাস্তবায়ন। প্রক্রিয়াটি তিনটি ডেটা সংস্করণ নিয়ে কাজ করে: বেস (বিচ্যুতির আগের অবস্থা), স্থানীয় (বর্তমান ক্লায়েন্টের সংস্করণ) এবং দূরবর্তী (সার্ভার সংস্করণ)। সিস্টেম কোন পক্ষ কোন ফিল্ড পরিবর্তন করেছে তা নির্ধারণ করতে স্থানীয় এবং দূরবর্তী সংস্করণের প্রতিটি ফিল্ড বেসের সাথে তুলনা করে।
সিদ্ধান্তের যুক্তি সহজ: যদি শুধুমাত্র একটি ক্লায়েন্ট ফিল্ড পরিবর্তন করে (বেসের সাপেক্ষে), তার পরিবর্তন স্বয়ংক্রিয়ভাবে গৃহীত হয়। যদি উভয় ক্লায়েন্ট একই ফিল্ড পরিবর্তন করে — একটি বিরোধ নথিভুক্ত হয় যা স্বয়ংক্রিয়ভাবে (অগ্রাধিকার দ্বারা) সমাধান করা যেতে পারে বা ব্যবহারকারীর কাছে অর্পণ করা যেতে পারে। যদি কোনো ক্লায়েন্ট ফিল্ড পরিবর্তন না করে — বেস মান রয়ে যায়। এই পদ্ধতি নিশ্চিত করে যে স্বাধীন পরিবর্তনগুলি neither হারিয়ে যায় nor বিরোধপূর্ণ হয়।
ফিল্ড ডিকশনারি স্তরে থ্রি-ওয়ে মার্জ অ্যালগরিদম:
fun threeWayMerge(
base: Map<String, Any?>,
local: Map<String, Any?>,
remote: Map<String, Any?>
): Map<String, Any?> {
val result = base.toMutableMap()
val allKeys = base.keys + local.keys + remote.keys
allKeys.forEach { key ->
val baseVal = base[key]
val localVal = local[key]
val remoteVal = remote[key]
result[key] = when {
localVal == baseVal -> remoteVal
remoteVal == baseVal -> localVal
localVal == remoteVal -> localVal
else -> // real conflict
resolveConflict(key, localVal, remoteVal)
}
}
return result
}
threeWayMerge ফাংশনটি তিনটি সংস্করণ থেকে সমস্ত কী ক্রমান্বয়ে প্রক্রিয়া করে। যদি স্থানীয় মান বেসের সাথে মেলে — দূরবর্তী পরিবর্তন গৃহীত হয়। যদি দূরবর্তী বেসের সাথে মেলে — স্থানীয় পরিবর্তন গৃহীত হয়। যদি উভয়ই বেস থেকে ভিন্ন কিন্তু একে অপরের সমান — যেকোনোটি গৃহীত হয়। একটি বাস্তব বিরোধ শুধুমাত্র তখনই নথিভুক্ত হয় যখন উভয় পক্ষের ভিন্ন ভিন্ন পরিবর্তন থাকে।
স্বয়ংক্রিয় নিষ্পত্তি প্রয়োগ করা হয় যখন পরিবর্তনগুলি ওভারল্যাপ না করে বা যখন সিস্টেম নিয়মের ভিত্তিতে সঠিক মান নির্ধারণ করতে পারে। উদাহরণস্বরূপ, সংখ্যাসূচক ফিল্ডের জন্য সর্বোচ্চ মান নির্বাচন করা যেতে পারে, টেক্সট ফিল্ডের জন্য — সংযুক্তিকরণ বা নতুন সংস্করণ। CouchDB JSON ডকুমেন্ট ফিল্ডের জন্য স্বয়ংক্রিয় মার্জ ব্যবহার করে, এবং অ্যারের জন্য — ডুপ্লিকেট অপসারণ সহ সংযুক্তিকরণ।
ম্যানুয়াল নিষ্পত্তি প্রয়োজনীয় যখন দুই ব্যবহারকারী একই ফিল্ড ভিন্নভাবে পরিবর্তন করে। এই ক্ষেত্রে, অ্যাপ্লিকেশন তিনটি বিকল্প সহ একটি ডায়ালগ দেখায়: “স্থানীয় সংস্করণ গ্রহণ করুন”, “দূরবর্তী সংস্করণ গ্রহণ করুন” বা “ম্যানুয়ালি মার্জ করুন”। CMU (কার্নেগি মেলন বিশ্ববিদ্যালয়, 2024)-এর গবেষণা অনুসারে, ম্যানুয়াল নিষ্পত্তি ব্যবহারকারীর সন্তুষ্টি 40% হ্রাস করে, তাই স্বয়ংক্রিয় মার্জ সর্বাধিক করা উচিত।
বিভিন্ন ফিল্ড প্রকারের জন্য নিষ্পত্তি কৌশল:
| ফিল্ডের ধরন | স্বয়ংক্রিয় কৌশল | ম্যানুয়াল বিকল্প |
|---|---|---|
| সংখ্যা (কাউন্টার) | সর্বোচ্চ নিন | উভয় মান দেখান |
| টেক্সট (স্ট্রিং) | সময় অনুযায়ী নির্বাচন | হাইলাইটেড এডিটর |
| বুলিয়ান | ভূমিকা অনুযায়ী অগ্রাধিকার | তিনটি নির্বাচন বিকল্প |
| অ্যারে (তালিকা) | ডিডুপ্লিকেশন সহ মার্জ | উপাদান-ভিত্তিক নির্বাচন |
| নেস্টেড অবজেক্ট | পুনরাবৃত্তিমূলক মার্জ | পার্থক্য দেখান |
আসুন বিবেচনা করি REST API-এর মাধ্যমে সিঙ্ক্রোনাইজেশন সহ মোবাইল অ্যাপ্লিকেশনে ব্যবহারকারীর প্রোফাইলের জন্য মার্জ স্ট্র্যাটেজির বাস্তবায়ন। প্রোফাইলে নাম, ইমেল, অবতার এবং বিজ্ঞপ্তি সেটিংস অন্তর্ভুক্ত। প্রতিটি ফিল্ড বিভিন্ন ব্যবহারকারী ডিভাইসে স্বাধীনভাবে পরিবর্তন করা যেতে পারে।
ফিল্ড-স্তরের সংস্করণায়ন সহ প্রোফাইল ডেটা ক্লাস:
data class UserProfile(
val displayName: String,
val email: String,
val avatarUrl: String,
val notificationsEnabled: Boolean
)
data class ProfileSnapshot(
val profile: UserProfile,
val version: Int
)
fun mergeProfiles(
base: UserProfile,
local: UserProfile,
remote: UserProfile
): UserProfile {
return UserProfile(
displayName = if (local.displayName != base.displayName)
local.displayName else remote.displayName,
email = if (local.email != base.email)
local.email else remote.email,
avatarUrl = if (remote.avatarUrl != base.avatarUrl)
remote.avatarUrl else local.avatarUrl,
notificationsEnabled = if (local.notificationsEnabled != base.notificationsEnabled)
local.notificationsEnabled
else remote.notificationsEnabled
)
}
mergeProfiles ফাংশন প্রোফাইলের প্রতিটি ফিল্ড স্বাধীনভাবে প্রক্রিয়া করে, বেস থেকে ভিন্ন সংস্করণটি নির্বাচন করে। বিরোধের ক্ষেত্রে (উভয়ই বেস থেকে ভিন্ন), অগ্রাধিকার অ্যাপ্লিকেশন নিয়ম দ্বারা নির্ধারিত হয়। উদাহরণে, avatarUrl-এর জন্য দূরবর্তী সংস্করণকে অগ্রাধিকার দেওয়া হয়, বাকি ফিল্ডের জন্য — স্থানীয়কে।
CouchDB এবং PouchDB হল সবচেয়ে পরিচিত ডেটাবেস যা অন্তর্নির্মিত মার্জ স্ট্র্যাটেজি সমর্থন সহ। ডকুমেন্ট প্রতিলিপির সময়, CouchDB ডকুমেন্ট স্তরে বিরোধ সনাক্তকরণ সহ মাল্টি-থ্রেডেড প্রতিলিপি ব্যবহার করে। বেস সংস্করণটি সংশোধন ইতিহাসে সংরক্ষিত হয়, এবং বিরোধের ক্ষেত্রে, সিস্টেম সমস্ত বিরোধপূর্ণ শাখা সংরক্ষণ করে এবং অ্যাপ্লিকেশনকে মার্জ প্রক্রিয়ার মাধ্যমে সেগুলি সমাধানের জন্য API প্রদান করে।
Firebase Firestore-এ, মার্জ আশাবাদী লকিং সহ লেনদেনের মাধ্যমে বাস্তবায়িত হয়। ডেভেলপার নির্দিষ্ট করতে পারে যে কিছু ফিল্ড FieldValue.serverTimestamp() এবং FieldValue.arrayUnion() ব্যবহার করে পারমাণবিকভাবে আপডেট করা উচিত। তবে, Firestore সম্পূর্ণ থ্রি-ওয়ে মার্জ সমর্থন করে না — বিরোধের ক্ষেত্রে, লেনদেন নতুন ডেটা সহ পুনরায় চেষ্টা করা হয়, যা প্রকৃত মার্জের পরিবর্তে পুনরায় চেষ্টার সমতুল্য।
Kotlin Multiplatform এবং React Native-এ মোবাইল অ্যাপ্লিকেশনের জন্য, মার্জ স্ট্র্যাটেজি ক্লায়েন্ট পাশে বাস্তবায়িত হয়। স্থানীয় ডেটাবেস (SQLite, Realm) প্রতিটি ডকুমেন্টের সংস্করণ সংরক্ষণ করে, এবং সিঙ্ক্রোনাইজেশনের সময়, ক্লায়েন্ট সার্ভার সংস্করণ লোড করে এবং ফলাফল পাঠানোর আগে স্থানীয়ভাবে মার্জ করে। এই পদ্ধতি দীর্ঘায়িত অফলাইন অপারেশনের সময়ও ডেটা অখণ্ডতা নিশ্চিত করে যখন আরও বিরোধ জমা হয়।
সচরাচর জিজ্ঞাসিত প্রশ্ন
মার্জ স্ট্র্যাটেজি বিরোধ নিষ্পত্তির একটি পদ্ধতি যেখানে বিভিন্ন সংস্করণের পরিবর্তনগুলি একটি একক অবস্থায় একত্রিত করা হয়। LWW-এর বিপরীতে, মার্জ উভয় শাখা থেকে পরিবর্তনগুলি সংরক্ষণ করে যদি তারা ফিল্ড স্তরে একে অপরের সাথে বিরোধপূর্ণ না হয়।
থ্রি-ওয়ে মার্জ নির্ধারণ করতে একটি বেস সংস্করণ (বিচ্যুতির আগের অবস্থা) ব্যবহার করে যে প্রতিটি ক্লায়েন্ট কোন ফিল্ড পরিবর্তন করেছে। টু-ওয়ে মার্জ মূল অবস্থা না জেনে শুধুমাত্র দুটি সংস্করণ তুলনা করে, যা প্রায়শই মিথ্যা বিরোধের দিকে নিয়ে যায়।
CouchDB এবং PouchDB-এর অন্তর্নির্মিত থ্রি-ওয়ে মার্জ সমর্থন রয়েছে। Firebase Firestore-এর লেনদেন স্তরে বাস্তবায়ন প্রয়োজন। MongoDB এবং Realm আশাবাদী লকিং প্রক্রিয়া প্রদান করে কিন্তু সম্পূর্ণ স্বয়ংক্রিয় মার্জ নয়।
মার্জ উপযুক্ত নয় সেই ডেটার জন্য যেখানে প্রক্রিয়াকরণের গতি গুরুত্বপূর্ণ (প্রতি সেকেন্ডে 1000-এর বেশি বিরোধ), স্ট্রিমিং ডেটা (লগ, ইভেন্ট) এবং সেই ক্ষেত্রের জন্য যেখানে পরিবর্তনগুলি মৌলিকভাবে অসামঞ্জস্যপূর্ণ (বিভিন্ন স্কিমা সংস্করণ)। এই ক্ষেত্রে, LWW বা CRDT আরও কার্যকর হবে।
বাস্তবায়নে তিনটি ধাপ অন্তর্ভুক্ত: সার্ভার থেকে ডেটা লোড করার সময় বেস সংস্করণ সংরক্ষণ, সংরক্ষণের সময় ফিল্ড স্তরে পরিবর্তন সনাক্তকরণ এবং সিঙ্ক্রোনাইজেশনের সময় মার্জ অ্যালগরিদম কল করা। সরলতার জন্য, JSON Patch বা CRDT লাইব্রেরি ব্যবহার করুন।
সারসংক্ষেপ
আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব
IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন