SQL Server change tracking
No edit summary
No edit summary
Line 67: Line 67:
  SET @last_sync_version = 1;   
  SET @last_sync_version = 1;   
  SELECT *,CAST(Sys_Change_Context AS VARCHAR(10)) as context FROM CHANGETABLE (CHANGES Aktualitet, @last_sync_version) AS C;
  SELECT *,CAST(Sys_Change_Context AS VARCHAR(10)) as context FROM CHANGETABLE (CHANGES Aktualitet, @last_sync_version) AS C;
Krux med att CHangeTracking bara har sista. Om främling skriver och vi skriver efter så kanske vi missar främlling.
Om vi skulle läsa om hela raden alltid vid upptäckt changetrack så får vi dublett om det var vi som skrev - inte hela värden. Det kanske blir trögt att inavlidera allt på ett objekt - men ser ingen annan råd då vi saknar precision
Men om vi alltid ska läsa om alla ändringar så behöver vi inte sätta kontext för våra skriv
Så förslaget är:
En idé är att låta utvecklaren välja själv i databasen vilka tabeller som ska ha change tracking.
Sen skapa en en operator som kan användas från MDrivenServer-Serverside-jobs typ:
selfVM.ServerSide_CheckChangeTracking(Person)
Vad den operatorn skulle göra är att hitta pk's som är externt ändrade samt skicka dessa med en ny typ av updateRequest som gör att alla persisterade members läggs i changepacke och landar därmed i Synk-listan - som styr refresh
Man skulle då helt själv med serversidejob styra hur ofta - och vad som behöver läsas om så här.

Revision as of 20:43, 18 April 2018

Tracking of changes is available from Sql Server 2008 and in Azure SQL. It's available in the Express editions, so you can use it in the build in Turnkey database.

To turn change tracking On, do like this

ALTER DATABASE AdventureWorks2012  
SET CHANGE_TRACKING = ON  
(CHANGE_RETENTION = 2 DAYS, AUTO_CLEANUP = ON) 
More reading

https://docs.microsoft.com/en-us/sql/relational-databases/track-changes/about-change-tracking-sql-server

See also when implementing

Article with a lot of details: https://docs.microsoft.com/en-us/sql/relational-databases/track-changes/work-with-change-tracking-sql-server

Setting Context Information provides a way to know that the MDrivenServer is the source of the change

Maybe last_synchronization_version can be used to know if ANY change has occured

-- Check all tables with change tracking enabled  
IF EXISTS (
    SELECT COUNT(*) FROM sys.change_tracking_tables
    WHERE min_valid_version > @last_synchronization_version )
  BEGIN
    -- Handle invalid version & do not enumerate changes
    -- Client must be reinitialized
  END

Implementation notes

Skapade rader, ändrade rader

DBChange.ChangeKind.MembersChanged med MemberIds=-1  (hela raden invalideras)

Borttagna rader

DBChange.ChangeKind.ObjectDeleted

Om jag stoppar in ChangeTrack info i samma kö som DBChange så måste jag översätta ChangeTrackId till VersionId

Det skulle bara vara 1(MDrivenServer) som frågar db changetrack(innan den svarar på Changes från klient) - minns vad som sagts med skapade DBChange rader

Klienten är omedveten - frågar bara efter DBChange

Kruxet är att "vanliga" ändringar kommer även generera changetrack som generar nya DBChange

Det gör att vi får dubbla DBChange - vilket kommer leda till att alla kliener som sparar nått kommer vilja läsa om det

(vilket i princip är rätt för att fixa fallet med en trigger som ändrar ett annat fält på samma rad som sidoeffekt)

MEN om insert/update/Delete skickar WITH CHANGE_TRACKING_CONTEXT ("MDrivenServer") så kan vi ignorera våra egna ändringar

Då borde vi även kunna fylla ett datablock med hela radensdata så att det skulle funka med synk

ALTER DATABASE Kubik  SET CHANGE_TRACKING = ON  
(CHANGE_RETENTION = 2 DAYS, AUTO_CLEANUP = ON)

ALTER TABLE Aktualitet ENABLE CHANGE_TRACKING  WITH (TRACK_COLUMNS_UPDATED = OFF) 

Måste slå på ChangeTracking per tabell

DECLARE @next_baseline bigint;  
SET @next_baseline = CHANGE_TRACKING_CURRENT_VERSION(); 
select @next_baseline DECLARE @context varbinary(14); 

set @context=CAST('MDrivenServer' AS VARBINARY); 
WITH CHANGE_TRACKING_CONTEXT (@context) 
update Aktualitet set namn='Arbetar nu4' where AktualitetID=1 

DECLARE @last_sync_version bigint;  
SET @last_sync_version = 1;  
SELECT *,CAST(Sys_Change_Context AS VARCHAR(10)) as context FROM CHANGETABLE (CHANGES Aktualitet, @last_sync_version) AS C;

Krux med att CHangeTracking bara har sista. Om främling skriver och vi skriver efter så kanske vi missar främlling.

Om vi skulle läsa om hela raden alltid vid upptäckt changetrack så får vi dublett om det var vi som skrev - inte hela värden. Det kanske blir trögt att inavlidera allt på ett objekt - men ser ingen annan råd då vi saknar precision

Men om vi alltid ska läsa om alla ändringar så behöver vi inte sätta kontext för våra skriv

Så förslaget är:

En idé är att låta utvecklaren välja själv i databasen vilka tabeller som ska ha change tracking.

Sen skapa en en operator som kan användas från MDrivenServer-Serverside-jobs typ:

selfVM.ServerSide_CheckChangeTracking(Person)

Vad den operatorn skulle göra är att hitta pk's som är externt ändrade samt skicka dessa med en ny typ av updateRequest som gör att alla persisterade members läggs i changepacke och landar därmed i Synk-listan - som styr refresh

Man skulle då helt själv med serversidejob styra hur ofta - och vad som behöver läsas om så här.

This page was edited 47 days ago on 03/26/2024. What links here