Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
La replica di tipo merge consente a più nodi di apportare modifiche ai dati autonome, pertanto esistono situazioni in cui una modifica apportata a un nodo potrebbe essere in conflitto con una modifica apportata agli stessi dati in un altro nodo. In altre situazioni, l'agente di merge rileva un errore, ad esempio una violazione del vincolo e non può propagare una modifica apportata a un determinato nodo in un altro nodo. Questo articolo descrive i tipi di conflitti, il modo in cui vengono rilevati e risolti i conflitti e fattori che influiscono sul rilevamento e sulla risoluzione.
Rilevare e risolvere i conflitti
L'agente di merge rileva i conflitti utilizzando la lineage
colonna della MSmerge_contents
tabella di sistema. Se il rilevamento a livello di colonna è abilitato per un articolo, viene utilizzata anche la COLV1
colonna . Queste colonne contengono metadati relativi all'inserimento o all'aggiornamento di una riga o di una colonna e sui nodi della topologia di replica a unione che hanno apportato modifiche alla riga o alla colonna. È possibile utilizzare la procedura memorizzata di sistema sp_showrowreplicainfo per visualizzare questi metadati.
Quando il Merge Agent enumera le modifiche da applicare durante la sincronizzazione, confronta i metadati per ogni riga al Publisher e al Subscriber. L'agente di merge usa questi metadati per determinare se una riga o una colonna è stata modificata in più nodi della topologia, che indica un potenziale conflitto. Dopo aver rilevato un conflitto, l'agente di merge avvia il sistema di risoluzione dei conflitti specificato per l'articolo con un conflitto e usa il sistema di risoluzione per determinare il vincitore del conflitto. La riga vincente viene applicata sia al Pubblicatore che al Sottoscrittore e i dati della riga perdente vengono scritti in una tabella dei conflitti.
I conflitti vengono risolti automaticamente e immediatamente dall'agente di merge, a meno che non sia stata scelta la risoluzione interattiva dei conflitti per l'articolo. Per altre informazioni, vedere Microsoft Replication Interactive Conflict Resolver. Se si modifica manualmente la riga vincente per un conflitto utilizzando il Visualizzatore conflitti di replica di tipo merge, l'agente di merge applica la versione vincente della riga al server in perdita durante la sincronizzazione successiva.
Registra conflitti risolti
Dopo che l'agente di merge ha risolto il conflitto in base alla logica nel sistema di risoluzione dei conflitti, registra i dati dei conflitti in base al tipo di conflitto:
Per
UPDATE
i conflitti eINSERT
scrive la versione persa della riga nella tabella dei conflitti per l'articolo, denominata nel formatoconflict_<PublicationName>_<ArticleName>
. Le informazioni generali sui conflitti, ad esempio il tipo di conflitto, sono scritte nella tabellaMSmerge_conflicts_info
.Per i conflitti in
DELETE
, scrive la versione perdente della riga nella tabellaMSmerge_conflicts_info
. Quando un'eliminazione perde rispetto a un aggiornamento, non sono presenti dati per la riga persa (perché è stata eliminata), quindi non viene scritto nulla inconflict_<PublicationName>_<ArticleName>
.
Le tabelle dei conflitti per ogni articolo vengono create nel database di pubblicazione, nel database di sottoscrizione o in entrambi (impostazione predefinita), a seconda del valore specificato per il @conflict_logging
parametro di sp_addmergepublication
. Ogni tabella dei conflitti ha la stessa struttura dell'articolo su cui si basa, con l'aggiunta della origin_datasource_id
colonna. L'agente di merge elimina i dati dalla tabella dei conflitti se è precedente al periodo di conservazione dei conflitti per la pubblicazione, specificato usando il @conflict_retention
parametro di sp_addmergepublication
(il valore predefinito è 14 giorni).
La replica fornisce il Visualizzatore dei conflitti di replica e le stored procedure (sp_helpmergearticleconflicts
, sp_helpmergeconflictrows
e sp_helpmergedeleteconflictrows
) per visualizzare i dati dei conflitti. Per ulteriori informazioni, vedere Risoluzione dei conflitti per la replicazione di tipo merge.
Fattori che influiscono sulla risoluzione dei conflitti
Esistono due fattori che influiscono sul modo in cui l'agente di merge risolve un conflitto rilevato:
Tipo di sottoscrizione: client o server (se la sottoscrizione è una sottoscrizione pull o una sottoscrizione push non influisce sulla risoluzione dei conflitti).
Tipo di rilevamento dei conflitti utilizzato: a livello di riga, a livello di colonna o a livello di record logico.
Tipi di sottoscrizione
Quando si crea una sottoscrizione, oltre a specificare se si tratta di una sottoscrizione push o pull, specificare se si tratta di una sottoscrizione client o server; dopo la creazione di una sottoscrizione, il tipo non può essere modificato (nelle versioni precedenti di SQL Server, le sottoscrizioni client e server sono state denominate rispettivamente sottoscrizioni locali e globali).
Una sottoscrizione con un valore di priorità assegnato (da 0,00 a 99,99) viene chiamata sottoscrizione server; una sottoscrizione che usa il valore di priorità del server di pubblicazione viene chiamata sottoscrizione client. Inoltre, i Sottoscrittori con sottoscrizioni server possono ripubblicare i dati in altri Sottoscrittori. Nella tabella seguente vengono riepilogate le differenze principali e gli usi di ogni tipo di Sottoscrittore.
TIPO | Valore priorità | nr. utilizzato |
---|---|---|
Servidor | Assegnato dall'utente | Quando si desidera che i sottoscrittori diversi abbiano priorità diverse. |
Cliente | 0.00, ma le modifiche ai dati assumono il valore di priorità del Publisher dopo la sincronizzazione | Quando desideri che tutti i Sottoscrittori abbiano la stessa priorità e che il primo Sottoscrittore a unirsi con l'editore vinca il conflitto. |
Se una riga viene modificata in una sottoscrizione client, non viene assegnata alcuna priorità alla modifica finché la sottoscrizione non viene sincronizzata. Durante la sincronizzazione, alle modifiche dal Sottoscrittore viene assegnata la priorità del Pubblicatore e tale priorità viene mantenuta per le sincronizzazioni successive. In un certo senso, l'editore assume la proprietà della modifica. Questo comportamento consente al primo Sottoscrittore di eseguire la sincronizzazione con il server di pubblicazione per vincere i conflitti successivi con altri Sottoscrittori per una determinata riga o colonna.
Quando si modifica una riga in una sottoscrizione server, la priorità della sottoscrizione viene archiviata nei metadati per la modifica. Questo valore di priorità accompagna la riga modificata mentre si unisce alle modifiche in altri Sottoscrittori. Ciò garantisce che una modifica apportata da una sottoscrizione con priorità più alta non perda a una modifica successiva apportata da una sottoscrizione con priorità più bassa.
Una sottoscrizione non può avere un valore di priorità esplicito superiore a quello del relativo Editore. Il server di pubblicazione di primo livello in una topologia di replica di tipo merge ha sempre un valore di priorità esplicito pari a 100,00. Tutte le sottoscrizioni della pubblicazione devono avere un valore di priorità minore di questo valore. In una topologia di ripubblicazione:
Se il Sottoscrittore ripubblica i dati, la sottoscrizione deve essere una sottoscrizione server con un valore di priorità minore del server di pubblicazione sopra il Sottoscrittore.
Se il Sottoscrittore non ripubblica i dati (perché si trova a livello foglia dell'albero di ripubblicazione), la sottoscrizione deve essere una sottoscrizione client.
Per altre informazioni sulle sottoscrizioni e le priorità del server, vedere Esempio di risoluzione dei conflitti di merge in base al tipo di sottoscrizione e alle priorità assegnate.
Notifica dei conflitti ritardata
È possibile che si verifichi una notifica di conflitto ritardata con sottoscrizioni server con priorità di conflitto diverse. Si consideri lo scenario seguente, in cui le modifiche non in conflitto vengono scambiate tra il server di pubblicazione e un Sottoscrittore con priorità inferiore che causano modifiche in conflitto quando un Sottoscrittore con priorità più alta viene sincronizzato con il server di pubblicazione:
Il server di pubblicazione e un Sottoscrittore con priorità bassa, denominato LowPrioritySub, scambiano modifiche in diverse sincronizzazioni senza conflitti.
Un Sottoscrittore con priorità più alta, denominato HighPrioritySub, non è sincronizzato con il server di pubblicazione in un determinato periodo di tempo e ha apportato modifiche alle stesse righe apportate dal Sottoscrittore LowPrioritySub.
Il Sottoscrittore HighPrioritySub si sincronizza con il server di pubblicazione e vince i conflitti tra le modifiche e il Sottoscrittore LowPrioritySub perché ha una priorità più alta rispetto al Sottoscrittore LowPrioritySub. Ora il Publisher contiene le modifiche apportate dal Subscriber HighPrioritySub.
Il Sottoscrittore LowPrioritySub viene quindi unito al server di pubblicazione e scarica un numero elevato di modifiche a causa dei conflitti con il Sottoscrittore HighPrioritySub.
Questa situazione può diventare problematica quando il Sottoscrittore con priorità inferiore ha apportato modifiche alle stesse righe che ora sono considerate sconfitte nei conflitti. Ciò può comportare una perdita di tutte le modifiche apportate dal Sottoscrittore. Una possibile soluzione a questo problema consiste nell'assicurarsi che tutti i Sottoscrittori abbiano la stessa priorità, a meno che la logica di business non determini diversamente.
Livello di rilevamento
L'eventuale qualificazione di una modifica dei dati come conflitto dipende dal tipo di rilevamento dei conflitti impostato per un articolo: a livello di riga, a livello di colonna o a livello di record logico. Per altre informazioni sul rilevamento a livello di record logico, vedere Risoluzione Avanzata dei Conflitti di Replica Unione - Risoluzione nel Record Logico.
Quando i conflitti vengono riconosciuti a livello di riga, le modifiche apportate alle righe corrispondenti vengono giudicate in conflitto, indipendentemente dal fatto che le modifiche vengano apportate alla stessa colonna. Si supponga, ad esempio, che venga apportata una modifica alla colonna indirizzo di una riga del server di pubblicazione e che venga apportata una seconda modifica alla colonna numero di telefono della riga del Sottoscrittore corrispondente (nella stessa tabella). Con il rilevamento a livello di riga, viene rilevato un conflitto perché sono state apportate modifiche alla stessa riga. Con il rilevamento a livello di colonna, non viene rilevato alcun conflitto, perché sono state apportate modifiche a colonne diverse nella stessa riga.
Per il rilevamento a livello di riga e a livello di colonna, la risoluzione del conflitto è la stessa: l'intera riga di dati viene sovrascritta dai dati del vincitore del conflitto (per il rilevamento a livello di record logico, la risoluzione dipende dalla proprietà logical_record_level_conflict_resolution
dell'articolo ).
La semantica dell'applicazione determina in genere quale opzione di rilevamento usare. Ad esempio, se si aggiornano i dati dei clienti immessi contemporaneamente, ad esempio un indirizzo e un numero di telefono, è consigliabile scegliere il rilevamento a livello di riga. Se in questa situazione è stato scelto il rilevamento a livello di colonna, le modifiche apportate all'indirizzo del cliente in un'unica posizione e al numero di telefono del cliente in un'altra posizione non verranno rilevate come conflitti: i dati verrebbero uniti alla sincronizzazione e l'errore verrebbe perso. In altre situazioni, l'aggiornamento di singole colonne da siti diversi potrebbe essere la scelta più logica. Ad esempio, due siti potrebbero avere accesso a diversi tipi di informazioni statistiche su un cliente, ad esempio il livello di reddito e l'importo totale in dollari degli acquisti di carte di credito. La selezione del rilevamento a livello di colonna garantisce che entrambi i siti possano immettere i dati statistici per colonne diverse senza generare conflitti non necessari.
Annotazioni
Se l'applicazione non richiede il rilevamento a livello di colonna, è consigliabile usare il rilevamento a livello di riga (impostazione predefinita) perché in genere comporta prestazioni di sincronizzazione migliori. Se si utilizza il rilevamento delle righe, la tabella di base può includere un massimo di 1.024 colonne, ma le colonne devono essere filtrate dall'articolo in modo che venga pubblicato un massimo di 246 colonne. Se viene usato il rilevamento delle colonne, la tabella di base può includere un massimo di 246 colonne.
Tipi di conflitto
Anche se la maggior parte dei conflitti è correlata agli aggiornamenti (un aggiornamento in un nodo è in conflitto con un aggiornamento o un'eliminazione in un altro nodo), esistono altri tipi di conflitto. Ogni tipo di conflitto descritto in questa sezione può verificarsi durante la fase di caricamento o la fase di download dell'elaborazione unione. L'elaborazione del caricamento è la prima riconciliazione delle modifiche eseguite in una determinata sessione di merge ed è la fase in cui l'Agente di Merge replica le modifiche dal Sottoscrittore al Pubblicatore. I conflitti rilevati durante l'elaborazione vengono definiti conflitti di caricamento. L'elaborazione del download comporta lo spostamento delle modifiche dal server di pubblicazione al Sottoscrittore e si verifica dopo l'elaborazione del caricamento. I conflitti durante questa fase di elaborazione vengono definiti conflitti di download.
Per altre informazioni sui tipi di conflitto, vedere MSmerge_conflicts_info, in particolare le conflict_type
colonne e reason_code
.
Conflitti di aggiornamento tra aggiornamenti
L'agente di merge rileva conflitti di aggiornamento quando un aggiornamento a una riga (o colonna o record logico) in un nodo è in conflitto con un altro aggiornamento alla stessa riga in un altro nodo. Il comportamento del sistema di risoluzione predefinito in questo caso consiste nell'inviare la versione vincente della riga al nodo in perdita e registrare la versione di riga persa nella tabella dei conflitti dell'articolo.
Conflitti di aggiornamento-eliminazione
L'agente di merge rileva conflitti di eliminazione degli aggiornamenti quando un aggiornamento dei dati in un nodo è in conflitto con un'eliminazione in un altro. In questo caso, l'agente di merge aggiorna una riga; Tuttavia, quando l'agente di merge cerca tale riga nella destinazione, non riesce a trovare la riga perché è stata eliminata. Se il vincitore è il nodo che effettua l'aggiornamento della riga, l'eliminazione al nodo perdente viene scartata e l'agente di merge invia la riga appena aggiornata al perdente del conflitto. L'agente di merge registra informazioni sulla versione persa della riga nella tabella MSmerge_conflicts_info
.
Conflitti di modifica non riusciti
L'agente di merge genera questi conflitti quando non può applicare una modifica specifica. Ciò si verifica in genere a causa di una differenza nelle definizioni dei vincoli tra il server di pubblicazione e il Sottoscrittore e l'uso della NOT FOR REPLICATION
proprietà (NFR) sul vincolo. Gli esempi includono:
Conflitto di chiave esterna nel Sottoscrittore, che può verificarsi quando il vincolo lato Sottoscrittore non è contrassegnato come NFR.
Le differenze nei vincoli tra il Publisher e i Sottoscrittori, e i vincoli non vengono contrassegnati come NFR.
Mancata disponibilità di oggetti dipendenti nel Sottoscrittore. Ad esempio, se si pubblica una vista, ma non la tabella da cui dipende tale vista, si verifica un errore se si tenta di eseguire l'inserimento tramite tale vista nel Sottoscrittore.
Logica di filtro di join per una pubblicazione che non rispetta i vincoli di chiave primaria e chiave esterna. I conflitti possono verificarsi quando il motore relazionale di SQL Server tenta di rispettare un vincolo, ma l'agente di merge rispetta la definizione del filtro di join tra gli articoli. L'agente di merge non può applicare la modifica nel nodo di destinazione a causa dei vincoli a livello di tabella, che causano un conflitto.
I conflitti a causa di violazioni di vincoli univoci o della chiave primaria possono verificarsi se le colonne "Identity" sono definite per l'articolo e non si utilizza la gestione automatica delle identità. Può trattarsi di un problema se due Sottoscrittori usano lo stesso valore Identity per una riga appena inserita. Per ulteriori informazioni sulla gestione degli intervalli Identity, vedere Replicare le colonne Identity.
Conflitti dovuti alla logica di attivazione che impedisce all'agente di merge di inserire una riga nella tabella di destinazione. Si consideri un trigger di aggiornamento definito nel sottoscrittore; il trigger non è contrassegnato come NFR e include nella sua logica un
ROLLBACK
. Se si verifica un errore, il trigger genera unaROLLBACK
della transazione, che causa il rilevamento di un conflitto di modifica fallita da parte dell'agente di merge.
Contenuti correlati
- Replica di tipo merge
- MSmerge_conflicts_info (Transact-SQL)
- MSmerge_contents (Transact-SQL)
- sp_addmergepublication (Transact-SQL)
- sp_helpmergearticleconflicts (Transact-SQL)
- sp_helpmergeconflictrows (Transact-SQL)
- sp_helpmergedeleteconflictrows (Transact-SQL)
- Controllare il comportamento dei trigger e dei vincoli nella sincronizzazione
- Replica di tipo merge avanzata - Rilevamento e risoluzione dei conflitti
- Ripubblicare i dati