Konflikte bei Merge-Replikation via Web

DocSash

Neuer Benutzer
Beiträge
3
Hallo liebe DB-Forum-Community,

ich habe ein Problem auf einem SQL-Server dem ich einfach nicht auf die Schliche komme. Hier zunächst mal eben der Aufbau:

1 MS - SQL-Server 2016 Standard auf einem Windows-Server 2012 im Web
ca. 10 Mobile und stationäre Geräte mit SQL-Express + Access Frontend.

Die Geräte replizieren alle 15 min. (Internetverbindung vorausgesetzt) die Daten mit dem Server.

Klappt auch alles, erreichen alle den Server und replizieren munter vor sich hin.

Das Problem:

Es kommt sehr regelmäßig zu Konflikten bei denen sehr häufig die falschen Datensätze als Gewinner ausgewählt werden. Angepasste Konfliktlöser kommen leider nicht in Frage, da die Clients wie gesagt mit SQL-Express laufen. Der Standardkonfliktlöser (ist ja "spät gewinnt") würde theoretisch auch reichen, wenn er denn richtig "lösen" würde. Häufig ist es aber so, dass auf einem Gerät ein Eintrag gemacht wird, die Replikation findet statt, und der Eintrag wird verworfen, obwohl kein anderes Gerät diesen Datensatz zu diesem Zeitpunkt angefasst hat. Habe schon sämtliche möglichen Ursachen im Frontend analysiert, aber daran liegt es nicht.

Was mich skeptisch macht: wenn es zu einem Konflikt kommt, meldet der Konfliktlöser (sinngemäß): "Der Datensatz wurde sowohl auf [Servername] als auch auf [Gerätename] bearbeitet. Der Konfliktlöser hat [Servername] als Gewinner ausgewählt." Es kommt nie der Hinweis, dass ein Konflikt zwischen zwei Geräten stattgefunden hat, sondern immer zwischen einem Gerät und dem Server selbst.

Kann es eventuell sein, dass auf dem Server regelmäßig irgendwelche Standardroutinen laufen, die einen Update-Vorgang auslösen? Der Server enthält auf jeden Fall keine selbst programmierten SPs oder Trigger, ist wirklich nur eine reine Datenschleuder ohne irgendwelche Logik.

Ich stehe diesbezüglich momentan wirklich auf dem Schlauch, und wäre für jeden Hinweis oder Tipp dankbar.
 
Werbung:
Hm, einen Bug würde ich tatsächlich erst als allerletztes in Betracht ziehen. Ich habe zumindest bei einer Tabelle einen Timestamp für Änderungen eingebaut, um zu überprüfen, welcher DS gewinnt. Tatsächlich ist es immer der letzte. Die Frage ist vielmehr: vorher kommen diese Änderungen?

Also nochmal zum Verständnis: Feld 1 enthält Wert 0. Ich ändere auf einem Client Feld 1 in Wert 1. Repliziere. Feld 1 enthält wieder Wert 0. Auf dem Server ist ein Konflikt einsehbar, laut dem der Server als Konfliktgewinner ausgewählt wurde, weil dort angeblich an dem DS eine neuere Änderung stattgefunden hat, als die von meinem Gerät. Und da auf dem Server der Wert für Feld 1 zum Zeitpunkt der "ominösen" Änderung noch 0 war, wird dieser Wert beim replizieren natürlich auch zurückgeschrieben.
 
um sowas sicher zu handeln, benötigt man den Timestamp des COMMITS. Der Server schaut nicht in irgend ein Feld der Tabelle, um daran die Entscheidung für die Konfliktlösung festzumachen.
Um logical replication in PostgreSQL zu ermöglichen, hat 2ndQ in PG-Version 9.5 z.B. dieses Feature eingebau: Commit Timestamps. Aus den Release notes:

  • Allow recording of transaction commit time stamps when configuration parameter track_commit_timestamp is enabled (Álvaro Herrera, Petr Jelínek)

    Time stamp information can be accessed using functions pg_xact_commit_timestamp() and pg_last_committed_xact().


In der Doku zu pglogical steht daher dann auch folgerichtig unter pglogical.conflict_reolution als eine von 5 Möglichkeiten:

last_update_wins - the version of data with newest commit timestamp will be kept (this can be
either local or remote version)

Vermutlich wird M$SQL ähnlich arbeiten. Entweder gehen die Uhren fundamental unterschiedlich, oder es ist falsch implementiert. Ein Primary Key ist vorhanden?[/quote]
 
Primary Key ist in allen Tabellen vorhanden.

Der Server schaut nicht in irgend ein Feld der Tabelle, um daran die Entscheidung für die Konfliktlösung festzumachen.

Das hatte ich mir schon gedacht, habe das Feld nur hinzugefügt, um das überhaupt nachverfolgen zu können.

Wie kann ich denn im MS-SQL-Server den Zeitpunkt des Commits mitloggen? Und mindestens ebenso interessant wäre das Gerät, von dem der Commit kommt.
 
Werbung:
Also du sagst auf dem Server ist keinerlei Logik, auch keine Trigger richtig?

Meine erste Vermutung wäre, das andere Clients die Daten eventuell nicht verändern aber unnötige Updates auf Datensätze ausführen. Ich habe allerdings noch nie intensiv mit Replikation gearbeitet, ist erstmal nur eine Vermutung. Das der Zeitpunkt des COMITS sehr stark vom Zeitpunkt der Datensatzänderung abweicht glaube ich erstmal nicht, möglich wäre es natürlich.

Du kannst deine Tabelle beobachten. In der Vergangenheit habe ich das mit SQL Profiler (nicht mehr aktuell) schon getan, manchmal kommt man nur damit wirklich dahinter. Alternativ könnte auch ein Trigger zum loggen eingesetzt werden.
 
Zurück
Oben