chinesisch - vereinfacht   deutsch   Englisch (USA)   französisch   griechisch   holländisch   portugiesisch - iberisch   spanisch  

Home




Usenet Posting #3 - Trigeminal Software, Inc. (German)

Betreff: INFO: Einblick in die Replikations-"MSysConflicts"-Tabelle in Jet 4.0
(ursprünglich gepostet 23.5.99)
Diese neue Tabelle bei der Jet 4.0 Replikation ist der Schlüssel zur Erstellung von mächtigen benutzerdefinierten Konfliktlösern. Die Info hier erklärt den Aufbau dieser Tabelle.

Zuerst beachten Sie, dass bei Jet 4.0 Konflikte an alle Replikate gemeldet werden, nicht wie bisher nur an das verlierende Replikat. Sie können das alte Schema verwenden, um Konflikte zu finden: die TableDefs-Collection durchlaufen, und jede Tabelle, bei der die ConflictTable-Eigenschaft auf einen Tabellennamen gesetzt ist, hat Konflikte. Aber das wäre viel mehr Arbeit als nötig. Stattdessen kann eine neue Tabelle namens MSysConflicts verwendet werden; sie beinhaltet Metadaten über *alle* Konflikte in der Datenbank.

Eine wichtige Änderung sind die "Kind-Konflikte", die passieren, wenn ein Divergenz-Konflikt (z.B. ein doppelter Primärschlüssel in der Angestellten-Tabelle) dafür sorgt, dass einige Bestellungen und Bestelldetails gelöscht werden, die mit dem verlierenden Angestellten-Datensatz zusammenhängen.

DER AUFBAU VON MSYSCONFLICTS:

Die erste Sache, die Ihnen auffallen wird, ist, dass das Jet-Team sich mit GUIDs vergnügt! Aber machen Sie sich nichts daraus; die meisten davon, betreffen Sie nicht und jene, die Sie betreffen, sind einfach, wenn Sie sie einmal verstanden haben.

-BaseGuidSrc - Eine GUID, die zum GuidSrc-Feld in MSysGenHistory linkt. Von Jet intern verwendet, um im Fall, dass in einer Zeile mehrere Konflikte mit mehreren Quellen auftreten, den zuletzt aufgetretenen Konflikt zu ermitteln. Normalerweise uninteressant für Anwender.

-BaseRowGuid - Eine GUID, die zum s_GUID-Feld in der Konflikt-Tabelle linkt. Sie repräsentiert den "Eltern"-Konflikt, daher enthalten alle Kind-Konflikte die gleiche BaseRowGuid als Eltern. Wenn sie übereinstimmt mit der ConflictIdGuid, dann handelt es sich um den Eltern-Konflikt.

-BaseTableGuid - Linkt zum s_GUID-Feld in MSysTableGuids und liefert Ihnen daher den Namen der Quelltabelle des Konflikts.

-ConflictDescCode - Konflikttyp - d.h. eindeutiger Schlüssel, TLV, simultanes Update, Fremdschlüssel etc.

-ConflictIdGuid - Eine GUID, die zum s_GUID-Feld in der Tabelle linkt. Wenn sie ident ist mit der BaseRowGuid, dann ist es der Eltern-Konflikt, sonst ist es ein Kind-Konflikt.

-InvolvedObjects - Ein Textfeld, dass Ihnen theoretisch Auskunft gibt, wo der Konflikt passierte, also Tabelle und Feld... in der Praxis habe ich noch nie gesehen, dass etwas drin stand.

-LosingReplicaId - Linkt zum s_GUID-Feld in MSysReplicas und sagt Ihnen, welches Replikat verloren hat.

-Reason - Text, der eine kontextsensitive Info über den Konflikt gibt, zur Anzeige gedacht.

-WinningGuidSrc - Linkt zum GuidSrc-Feld in MSysGenHistory. Wie BaseGuidSrc von Jet intern verwendet, um im Fall, dass in einer Zeile mehrere Konflikte mit mehreren Quellen auftreten, den zuletzt aufgetretenen Konflikt zu ermitteln. Normalerweise uninteressant für Anwender.

-WinningReplicaId - Linkt zum s_GUID-Feld in MSysReplicas und sagt Ihnen, welches Replikat gewonnen hat.

-WinningRowGuid - Linkt zum s_GUID-Feld der Quelltabelle, wenn es noch eine Quellzeile gibt, auf die Sie sich beziehen möchten (wie z.B. in einem Update-Update-Konflikt oder in einem Konflikt wegen doppelter Primärschlüssel).

-s_GUID - Replikations-Systemfeld... linkt zum ConflictRowGuid in der Konflikttabelle, wenn Sie den Link brauchen.

-s_Generation - Replikations-Systemfeld...

-s_Lineage - Replikations-Systemfeld....

OK... gehen wir mal davon aus, sie möchten folgendes machen:
1) Alle Eltern-Konflikte auflisten, aber keine Kind-Konflikte
2) Die verlierenden und gewinnenden Replikate anzeigen
3) Die Anzahl der Konflikte und die Anzahl der Kind-Konflikte anzeigen
4) Den Namen der Konflikttabelle anzeigen und den der Quelltabelle

Sie könnten das alles mit einer Abfrage wie der folgenden machen:

SELECT 
    Max(tg.TableName) AS src_Table, 
    Max(st.SideTable) AS conflict_table, 
    Count(IIF(c_a.ConflictIdGuid <> c_a.s_Guid,Null, 1)) As CnfCount, 
    Count(IIF(c_a.ConflictIdGuid = c_a.s_Guid, Null, 1)) As 
CnfChildCount 
FROM 
    (((MSysTableGuids AS tg INNER JOIN 
    MSysSideTables AS st ON tg.s_GUID = st.TableGuid) INNER 
JOIN 
    MSysConflicts AS c ON st.TableGuid = c.BaseTableGuid) 
INNER JOIN 
    MSysReplicas AS r ON c.WinningReplicaId = r.ReplicaId) 
INNER JOIN 
    MSysConflicts AS c_a ON c_a.ConflictIdGuid = c.s_Guid 
WHERE 
    c.ConflictIDGuid = c.s_Guid 
GROUP BY 
    tg.TableName; 

Das gibt ein hübsches Ergebnis mit allen Quell- und Konflikttabellen, ebenso die Anzahl der Konflikte und der dazugehörigen Kind-Konflikte. Und wenn Sie durch die Konflikte scrollen und die kompletten Quell- und Konfliktspalten z.B. für die Tabelle Customers in ein einziges Recordset bekommen möchten:

SELECT 
    Customers.*, 
    Customers_Conflict.* 
FROM 
    (Customers_Conflict INNER JOIN 
    MSysConflicts ON Customers_Conflict.ConflictRowGuid = MSysConflicts.s_GUID) LEFT JOIN 
    Customers ON MSysConflicts.WinningRowGuid = Customers.s_GUID 

Von dort brauchen Sie die Info nur noch abzuholen...

Zu dem Thema wird mit der Zeit sicher noch mehr kommen, aber zuerst einmal den Aufbau durchzugehen schien mit ein guter erster Schritt.

Home

Probleme mit dieser Seite? Bitte kontaktieren Sie den webmaster@trigeminal.com
mit Ihren Kommentaren, Fragen oder Vorschlägen.