Merge Strategy — шта је то, типови спајања и принцип рада

Аутор: IT Sectr Објављено: 2026-06-14 Време читања: 8 мин

Merge Strategy — стратегија спајања података при којој се конфликтне измене из различитих верзија обједињују у јединствено усаглашено стање уместо замене једне верзије другом. За разлику од Last Write Wins, спајање покушава да сачува измене из свих грана, минимизирајући губитак података. Према Apache CouchDB documentation, 2025, тространо спајање (three-way merge) је стандардни механизам за решавање конфликата у документ-оријентисаним базама података. Тространо спајање користи заједничку базну верзију за одређивање која поља је изменио сваки клијент.

Главно

  • Merge Strategy — приступ при коме се конфликтне измене обједињују, а не замењују, што минимизира губитак корисничких података.
  • Тространо спајање — анализира локалну, удаљену и базну верзију, аутоматски решавајући неконфликтне измене на нивоу поља.
  • Чување историје — Merge захтева чување претходних верзија за одређивање разлика, што повећава обим ускладиштених података.
  • Сложеност — Merge је сложенији за имплементацију од LWW, посебно за решавање конфликата угнежђених структура и низова.
  • Примена — оптималан за профиле, документе, форме и друге структуриране податке где свако поље има независну вредност.

Шта је Merge Strategy у мобилном развоју?

Merge Strategy — скуп алгоритама који обједињују конфликтне верзије података уместо избора једне од њих. У мобилним апликацијама, Merge се користи када два клијента независно уређују различита поља или својства истог објекта. Уместо да одбаци старију верзију у целини (као у LWW), систем анализира разлике на нивоу појединачних поља и формира резултујући објекат који садржи измене из обе верзије.

Кључна разлика Merge у односу на LWW — чување измена сваког корисника под условом да нису у међусобној супротности. Ако је корисник А променио назив задатка, а корисник Б — опис, Merge ће сачувати обе измене. Ако су оба променила исто поље — бележи се конфликт који захтева решавање. Ово чини Merge пожељним за апликације у којима корисници заједно раде на истим подацима.

Према извештају Stripe Engineering Blog (2025), имплементација Merge Strategy уместо LWW смањила је број жалби корисника на губитак података за 76% у њиховој мобилној апликацији за управљање пројектима. Међутим, време обраде конфликата се повећало за 15–30 ms, што се сматра прихватљивом ценом за очување информација.

Тространо спајање: како механизам ради

Тространо спајање (three-way merge) — најраспрострањенија имплементација Merge Strategy. Механизам оперише са три верзије података: базном (base — стање пре дивергенције), локалном (local — верзија тренутног клијента) и удаљеном (remote — верзија са сервера). Систем пореди свако поље локалне и удаљене верзије са базном да би одредио која страна је изменила која поља.

Логика доношења одлука је једноставна: ако је поље изменио само један клијент (у односу на базу), његова измена се прихвата аутоматски. Ако су оба клијента изменила исто поље — бележи се конфликт који може бити решен аутоматски (по приоритету) или прослеђен кориснику. Ако ниједан клијент није мењао поље — остаје базна вредност. Овакав приступ гарантује да се независне измене не губе и не конфликтују.

Алгоритам т страног спајања на нивоу речника поља:

kotlin
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 -> // прави конфликт
                resolveConflict(key, localVal, remoteVal)
        }
    }
    return result
}

Функција threeWayMerge секвенцијално обрађује све кључеве из три верзије. Ако се локална вредност поклапа са базном — прихвата се удаљена измена. Ако се удаљена поклапа са базном — прихвата се локална. Ако се обе разликују од базе, али су једнаке међу собом — било која. Прави конфликт се бележи само при различитим изменама са обе стране.

Аутоматско и ручно решавање конфликата

Аутоматско решавање се примењује када се измене не преклапају или када систем може да одреди тачну вредност на основу правила. На пример, за нумеричка поља може се изабрати максимална вредност, за текстуална — конкатенација или новија верзија. CouchDB користи аутоматско спајање за поља JSON документа, а за низове — конкатенацију са уклањањем дупликата.

Ручно решавање је неопходно када су два корисника изменила исто поље на различите начине. У овом случају, апликација приказује дијалог са три опције: „прихвати локалну верзију”, „прихвати удаљену верзију” или „споји ручно”. Аутори истраживања CMU (Carnegie Mellon University, 2024) напомињу да ручно решавање смањује задовољство корисника за 40%, стога аутоматско спајање треба максимизирати.

Стратегије решавања за различите типове поља:

Тип пољаАутоматска стратегијаРучна алтернатива
Број (бројач)Узети максималниПриказати обе вредности
Текст (ниска)Изабрати по временуУређивач са истицањем
Логичка вредностПриоритет по улогамаТри опције избора
Низ (листа)Обједињавање са дедупликацијомИзбор елемент по елемент
Угнежђени објекатРекурзивно спајањеПриказати diff

Примери имплементације спајања у Kotlin

Размотримо имплементацију Merge Strategy за профил корисника у мобилној апликацији са синхронизацијом преко REST API. Профил садржи име, email, аватар и подешавања обавештења. Свако поље може бити измењено независно на различитим уређајима корисника.

Data-класа профила са верзионисањем на нивоу поља:

kotlin
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 приоритет се даје удаљеној верзији, за остала поља — локалној.

Merge Strategy у базама података мобилних апликација

CouchDB и PouchDB — најпознатије базе са уграђеном подршком за Merge Strategy. При репликацији докумената, CouchDB користи вишепроцесну репликацију са детекцијом конфликата на нивоу документа. Базна верзија се чува у историји ревизија, а при конфликту систем чува све конфликтне гране и пружа апликацији API за њихово решавање кроз механизам спајања.

У Firebase Firestore, Merge је имплементиран кроз транзакције са оптимистичним закључавањем. Програмер може назначити да се одређена поља ажурирају атомично, користећи FieldValue.serverTimestamp() и FieldValue.arrayUnion(). Међутим, Firestore не подржава потпуно тространо спајање — при конфликту се транзакција понавља са новим подацима, што је еквивалентно поновном покушају, а не правом спајању.

За мобилне апликације на Kotlin Multiplatform и React Native, Merge Strategy се имплементира на клијентској страни. Локална база (SQLite, Realm) чува верзију сваког документа, а при синхронизацији клијент учитава верзију са сервера и извршава спајање локално пре слања резултата. Овакав приступ обезбеђује очување података чак и при дуготрајном раду ван мреже, када се накупи више конфликата.

Често постављана питања

Шта је Merge Strategy у синхронизацији података?

Merge Strategy — приступ решавању конфликата при коме се измене из различитих верзија обједињују у јединствено стање. За разлику од LWW, Merge чува измене из обе гране ако нису у међусобној супротности на нивоу поља.

Која је разлика између тстраног и двостраног спајања?

Тространо спајање користи базну верзију (стање пре дивергенције) за одређивање која поља је изменио сваки клијент. Двострано спајање пореди само две верзије, не знајући почетно стање, што чешће доводи до лажних конфликата.

Које базе података подржавају Merge из кутије?

CouchDB и PouchDB имају уграђену подршку за тространо спајање. Firebase Firestore захтева имплементацију на нивоу транзакција. MongoDB и Realm нуде механизме оптимистичног закључавања, али не потпуно аутоматско спајање.

Када Merge Strategy није прикладна?

Merge није прикладан за податке где је важна брзина обраде (преко 1000 конфликата у секунди), за токове података (логови, догађаји) и за случајеве када су измене принципијелно некомпатибилне (различите верзије шеме података). У овим случајевима, LWW или CRDT ће бити ефикаснији.

Како имплементирати Merge Strategy у мобилној апликацији?

Имплементација укључује три корака: чување базне верзије при учитавању података са сервера, детекцију измена на нивоу поља при чувању и позив алгоритма спајања при синхронизацији. За поједностављење користите библиотеке JSON Patch или CRDT.

Закључци

  • Merge Strategy — стратегија решавања конфликата која обједињује измене из различитих верзија података, а не замењује једну верзију другом.
  • Тространо спајање — најпопуларнија имплементација, која користи базну, локалну и удаљену верзију за одређивање измењених поља.
  • Аутоматско решавање — примењује се за неконфликтне измене (различита поља, један од клијената није мењао податке).
  • Ручно решавање — неопходно при измени истог поља од стране два клијента, али смањује задовољство корисника за 40%.
  • Предност — минималан губитак података и боље корисничко искуство при заједничком раду на документима.
  • Недостатак — повећана сложеност имплементације и додатно чување историје верзија у локалној бази података.
  • Препорука — примењујте Merge за профиле, документе и конфигурације. За метаподатке и логове користите LWW као једноставнију алтернативу.

Развићемо мобилну апликацију под кључ

IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту

Прочитајте такође