Aracılığıyla paylaş


Değişiklik izleme ile çalışma (SQL Server)

Şunlar için geçerlidir:SQL ServerAzure SQL VeritabanıAzure SQL Yönetilen ÖrneğiMicrosoft Fabric'te SQL veritabanı

Değişiklik izleme kullanan uygulamaların izlenen değişiklikleri edinebilmesi, bu değişiklikleri başka bir veri deposuna uygulayabilmesi ve kaynak veritabanını güncelleştirebilmesi gerekir. Bu makalede, bu görevlerin nasıl gerçekleştirileceği açıklanır ve yük devretme gerçekleştiğinde ve bir veritabanının yedekten geri yüklenmesi gerektiğinde rol değişikliği izleme de yürütülür.

Değişiklik izleme işlevlerini kullanarak değişiklikleri alma

Bir veritabanında yapılan değişikliklerle ilgili değişiklikleri ve bilgileri almak için değişiklik izleme işlevlerinin nasıl kullanılacağını açıklar.

Değişiklik izleme işlevleri hakkında

Uygulamalar, veritabanında yapılan değişiklikleri ve değişikliklerle ilgili bilgileri almak için aşağıdaki işlevleri kullanabilir:

  • CHANGETABLE(CHANGES ...) fonksiyon

    Bu satır kümesi işlevi, değişiklik bilgilerini sorgulamak için kullanılır. İşlev, iç değişiklik izleme tablolarında depolanan verileri sorgular. İşlev, işlem, güncelleştirilen sütunlar ve satır sürümü gibi diğer değişiklik bilgileriyle birlikte değiştirilen satırların birincil anahtarlarını içeren bir sonuç kümesi döndürür.

    CHANGETABLE(CHANGES ...) bağımsız değişken olarak son senkronizasyon sürümünü alır. Son eşitleme sürümü @last_synchronization_version değişkeni kullanılarak elde edilir. Son eşitleme sürümünün semantiği aşağıdaki gibidir:

  • Çağıran istemci değişiklikleri edindi ve son eşitleme sürümü dahil olmak üzere tüm değişiklikleri biliyor.

  • CHANGETABLE(CHANGES ...) bu nedenle, son eşitleme sürümünden sonra gerçekleşen tüm değişiklikleri döndürür.

Aşağıdaki çizimde, değişiklikleri almak için nasıl CHANGETABLE(CHANGES ...) kullanıldığı gösterilmektedir.

Değişiklik izleme sorgusu çıktısı örneğini gösteren diyagram.

Bu örnekte, İstemci A son olarak 09:30'da eşitlenirken, İstemci B son olarak 10:30'da eşitlendi. Saat 10:00'da ve tekrar 11:00'de verilerde çeşitli değişiklikler yapıldı. İzlenen bu değişiklikler aşağıdaki örnekte özetlenmiştir.

CHANGETABLE(CHANGES...) Çıkış - 11:30 ÖS

İstemci A en son 09:30'da eşitlendi.

Product ID İşlem Sütun
139 Güncelleştirmek Ad, Fiyat
140 Silmek -
141 Ekle -

İstemci B en son 10:30'da eşitlendi.

Product ID İşlem Sütun
139 Güncelleştirmek Fiyat
140 Silmek -
141 Güncelleştirmek Fiyat
  • CHANGE_TRACKING_CURRENT_VERSION() fonksiyon

    Değişiklikleri sorgularken bir sonraki sefer kullanılacak geçerli sürümü elde etmek için kullanılır. Bu sürüm, son işlenen işlemin sürümünü temsil eder.

  • CHANGE_TRACKING_MIN_VALID_VERSION() fonksiyon

    İstemcinin sahip olabileceği en düşük geçerli sürümü elde etmek ve yine de içinden CHANGETABLE()geçerli sonuçlar almak için kullanılır. İstemcinin son eşitleme sürümünü bu işlev tarafından döndürülen değerle karşılaştırarak denetlemesi gerekir. Son eşitleme sürümü bu işlev tarafından döndürülen sürümden küçükse, istemci geçerli CHANGETABLE() sonuçlar alamaz ve yeniden başlatması gerekir.

İlk verileri alma

Bir uygulamanın değişiklikleri ilk kez alabilmesi için önce uygulamanın ilk verileri ve eşitleme sürümünü almak için bir sorgu göndermesi gerekir. Uygulamanın doğrudan tablodan uygun verileri alması ve ardından ilk sürümü elde etmek için kullanması CHANGE_TRACKING_CURRENT_VERSION() gerekir. Bu sürüm, değişiklikler ilk kez elde edildiğinde CHANGETABLE(CHANGES ...) geçirilir.

Aşağıdaki örnekte, ilk eşitleme sürümünün ve ilk veri kümesinin nasıl edindiği gösterilmektedir.

declare @synchronization_version bigint;

-- Obtain the current synchronization version. This will be used next time that changes are obtained.
SET @synchronization_version = CHANGE_TRACKING_CURRENT_VERSION();

-- Obtain initial data set.
SELECT
    P.ProductID, P.Name, P.ListPrice
FROM
   SalesLT.Product AS P;

Değişiklikleri almak için değişiklik izleme işlevlerini kullanma

Bir tablonun değiştirilen satırlarını ve değişikliklerle ilgili bilgileri almak için kullanın CHANGETABLE(CHANGES...). Örneğin, aşağıdaki sorgu tablo için SalesLT.Product değişiklikleri alır.

declare @last_synchronization_version bigint;

SELECT
    CT.ProductID, CT.SYS_CHANGE_OPERATION,
    CT.SYS_CHANGE_COLUMNS, CT.SYS_CHANGE_CONTEXT
FROM
    CHANGETABLE(CHANGES SalesLT.Product, @last_synchronization_version) AS CT;

Genellikle, bir istemci yalnızca satırın birincil anahtarları yerine bir satır için en son verileri almak ister. Bu nedenle, bir uygulama sonuçları CHANGETABLE(CHANGES ...) kullanıcı tablosundaki verilerle birleştirir. Örneğin, aşağıdaki sorgu SalesLT.Product ve Name sütunlarının değerlerini almak için ListPrice tablosuyla birleşir. OUTER JOINkullanımına dikkat edin. Bu, kullanıcı tablosundan silinmiş olan satırlar için değişiklik bilgilerinin döndürülmesini sağlamak için gereklidir.

SELECT
    CT.ProductID, P.Name, P.ListPrice,
    CT.SYS_CHANGE_OPERATION, CT.SYS_CHANGE_COLUMNS,
    CT.SYS_CHANGE_CONTEXT
FROM
    SalesLT.Product AS P
RIGHT OUTER JOIN
    CHANGETABLE(CHANGES SalesLT.Product, @last_synchronization_version) AS CT
ON
    P.ProductID = CT.ProductID;

Sonraki değişiklik numaralandırmasında kullanılacak sürümü edinmek için, aşağıdaki örnekte gösterildiği gibi CHANGE_TRACKING_CURRENT_VERSION() kullanın.

SET @synchronization_version = CHANGE_TRACKING_CURRENT_VERSION();

Bir uygulama değişiklikleri edindiğinde, aşağıdaki örnekte gösterildiği gibi hem CHANGETABLE(CHANGES...) hem de CHANGE_TRACKING_CURRENT_VERSION() kullanmalıdır.

-- Obtain the current synchronization version. This will be used the next time CHANGETABLE(CHANGES...) is called.
SET @synchronization_version = CHANGE_TRACKING_CURRENT_VERSION();

-- Obtain incremental changes by using the synchronization version obtained the last time the data was synchronized.
SELECT
    CT.ProductID, P.Name, P.ListPrice,
    CT.SYS_CHANGE_OPERATION, CT.SYS_CHANGE_COLUMNS,
    CT.SYS_CHANGE_CONTEXT
FROM
    SalesLT.Product AS P
RIGHT OUTER JOIN
    CHANGETABLE(CHANGES SalesLT.Product, @last_synchronization_version) AS CT
ON
    P.ProductID = CT.ProductID;

Sürüm numaraları

Değişiklik izleme özelliğinin etkinleştirildiği bir veritabanında, izlenen tabloları değiştirmek için değişiklikler yapıldıkçe artan bir sürüm sayacı vardır. Değiştirilen her satırın kendisiyle ilişkilendirilmiş bir sürüm numarası vardır. Değişiklikleri sorgulamak için bir uygulamaya istek gönderildiğinde, sürüm numarası sağlayan bir işlev çağrılır. İşlev, bu sürümden bu yana yapılan tüm değişiklikler hakkında bilgi döndürür. Değişiklik izleme sürümü, kavram olarak rowversion veri türüne benzer.

Son eşitlenen sürümü doğrulama

Değişikliklerle ilgili bilgiler sınırlı bir süre boyunca korunur. Süre uzunluğu, CHANGE_RETENTION bileşeninin bir parçası olarak belirtilebilen ALTER DATABASE parametresiyle denetlenebilir.

için CHANGE_RETENTION belirtilen süre, tüm uygulamaların veritabanından ne sıklıkta değişiklik istemesi gerektiğini belirler. Bir uygulamanın değeri tablo için last_synchronization_version en düşük geçerli eşitleme sürümünden eskiyse, bu uygulama geçerli değişiklik numaralandırması gerçekleştiremez. Bunun nedeni bazı değişiklik bilgilerinin temizlenmiş olmasıdır. Bir uygulama CHANGETABLE(CHANGES ...) kullanarak değişiklikleri almadan önce, uygulamanın last_synchronization_version'ye geçirmeyi planladığı CHANGETABLE(CHANGES ...) değerini doğrulaması gerekir. değeri last_synchronization_version geçerli değilse, bu uygulamanın tüm verileri yeniden başlatması gerekir.

Aşağıdaki örnekte, her tablo için last_synchronization_version değerinin geçerliliğinin nasıl doğrulanması gösterilmektedir.

-- Check individual table.
IF (@last_synchronization_version < CHANGE_TRACKING_MIN_VALID_VERSION(
                                   OBJECT_ID('SalesLT.Product')))
BEGIN
  -- Handle invalid version and do not enumerate changes.
  -- Client must be reinitialized.
END;

Aşağıdaki örnekte gösterildiği gibi, last_synchronization_version değerinin geçerliliği veritabanındaki tüm tablolarda denetlenebilir.

-- Check all tables with change tracking enabled
IF EXISTS (
  SELECT 1 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;

Sütun izlemeyi kullan

Sütun izleme, uygulamaların satırın tamamı yerine yalnızca değiştirilen sütunlar için verileri almasını sağlar. Örneğin, bir tabloda büyük ancak nadiren değişen bir veya daha fazla sütunun bulunduğu senaryoyu göz önünde bulundurun; ve sık sık değişen başka sütunları da vardır. Sütun izleme olmadan, bir uygulama yalnızca bir satırın değiştiğini ve büyük sütun verilerini içeren tüm verileri eşitlemesi gerekeceğini belirleyebilir. Ancak, bir uygulama sütun izleme kullanarak büyük sütun verilerinin değişip değişmediğini belirleyebilir ve yalnızca değiştirildiğinde verileri eşitleyebilir.

Sütun izleme bilgileri, SYS_CHANGE_COLUMNS ve CHANGETABLE(CHANGES ...) işlevinin döndürdüğü sütunda görüntülenir.

Sütun izleme, değişmemiş bir sütun için NULL'in dönmesi için kullanılabilir. Eğer sütun NULL olarak değiştirilebiliyorsa, sütunun değişip değişmediğini belirtmek için ayrı bir sütun döndürülmelidir.

Aşağıdaki örnekte, CT_ThumbnailPhoto sütunu değişmediyse NULL olacaktır. Bu sütun, NULL olarak değiştirildiği için NULL de olabilir. Uygulama, CT_ThumbNailPhoto_Changed sütununu kullanarak sütunun değişip değişmediğini belirleyebilir.

DECLARE @PhotoColumnId int = COLUMNPROPERTY(
    OBJECT_ID('SalesLT.Product'),'ThumbNailPhoto', 'ColumnId');

SELECT
    CT.ProductID, P.Name, P.ListPrice, -- Always obtain values.
    CASE
           WHEN CHANGE_TRACKING_IS_COLUMN_IN_MASK(
                     @PhotoColumnId, CT.SYS_CHANGE_COLUMNS) = 1
            THEN ThumbNailPhoto
            ELSE NULL
      END AS CT_ThumbNailPhoto,
      CHANGE_TRACKING_IS_COLUMN_IN_MASK(
                     @PhotoColumnId, CT.SYS_CHANGE_COLUMNS) AS
                                   CT_ThumbNailPhoto_Changed,
     CT.SYS_CHANGE_OPERATION, CT.SYS_CHANGE_COLUMNS,
     CT.SYS_CHANGE_CONTEXT
FROM
     SalesLT.Product AS P
INNER JOIN
     CHANGETABLE(CHANGES SalesLT.Product, @last_synchronization_version) AS CT
ON
     P.ProductID = CT.ProductID AND
     CT.SYS_CHANGE_OPERATION = 'U';

Tutarlı ve doğru sonuçlar alma

Bir tablo için değiştirilen verilerin alınması için birden çok adım gerekir. Bazı sorunlar dikkate alınmaz ve işlenmezse tutarsız veya yanlış sonuçlar döndürülebilir.

Örneğin, bir Sales tablosunda ve SalesOrders tablosunda yapılan değişiklikleri almak için bir uygulama aşağıdaki adımları gerçekleştirebilir:

  1. kullanarak CHANGE_TRACKING_MIN_VALID_VERSION() son eşitlenmiş sürümü doğrulayın.

  2. CHANGE_TRACKING_CURRENT_VERSION() kullanarak bir sonraki seferde değişiklik elde etmek için kullanılabilecek sürümü edinin.

  3. Sales kullanarak CHANGETABLE(CHANGES ...) tablosundaki değişiklikleri alın.

  4. SalesOrders kullanarak CHANGETABLE(CHANGES ...) tablosundaki değişiklikleri alın.

Veritabanında, önceki adımlar tarafından döndürülen sonuçları etkileyebilecek iki işlem oluşuyor:

  • Temizleme işlemi arka planda çalışır ve belirtilen saklama süresinden daha eski olan değişiklik izleme bilgilerini kaldırır.

    Temizleme işlemi, veritabanı için değişiklik izlemeyi yapılandırırken belirtilen saklama süresini kullanan ayrı bir arka plan işlemidir. Sorun, temizleme işleminin son eşitleme sürümünün doğrulandığı zaman ile CHANGETABLE(CHANGES...) çağrısının yapıldığı zaman arasında gerçekleşebileceğidir. Geçerli olan son eşitleme sürümü, değişiklikler alındığında artık geçerli olmayabilir. Bu nedenle, yanlış sonuçlar döndürülebilir.

  • Sales ve SalesOrders tablolarında aşağıdaki işlemler gibi devam eden DML işlemleri gerçekleşir:

    • Bir sonraki kez için sürüm CHANGE_TRACKING_CURRENT_VERSION() kullanılarak elde edildikten sonra tablolarda değişiklik yapılabilir. Bu nedenle, beklenenden daha fazla sayıda değişiklik geri dönebilir.

    • bir işlem, Sales tablosundan değişiklikleri getirme çağrısı ile SalesOrders tablosundan değişiklikleri getirme çağrısı arasındaki süre içinde işlenebilir. Bu nedenle, SalesOrder tablosunun sonuçları, Sales tablosunda mevcut olmayan yabancı anahtar değerine sahip olabilir.

Daha önce listelenen zorlukların üstesinden gelmek için anlık görüntü yalıtımı kullanmanızı öneririz. Bu, değişiklik bilgilerinin tutarlılığını sağlamaya ve arka plan temizleme göreviyle ilgili yarış koşullarından kaçınmaya yardımcı olur. Anlık görüntü işlemlerini kullanmıyorsanız, değişiklik izleme kullanan bir uygulama geliştirmek önemli ölçüde daha fazla çaba gerektirebilir.

Anlık görüntü yalıtımını kullanma

Değişiklik izleme, anlık görüntü yalıtımıyla iyi çalışacak şekilde tasarlanmıştır. Veritabanı için anlık görüntü yalıtımı etkinleştirilmelidir. Değişiklikleri almak için gereken tüm adımlar anlık görüntü işlemine eklenmelidir. Bu, değişiklikler alınırken verilerde yapılan tüm değişikliklerin anlık görüntü işlemi içindeki sorgulara görünmemesini sağlar.

Anlık görüntü işlemi içindeki verileri almak için aşağıdaki adımları gerçekleştirin:

  1. İşlem yalıtım düzeyini anlık görüntü olarak ayarlayın ve bir işlem başlatın.

  2. CHANGE_TRACKING_MIN_VALID_VERSION() kullanarak son eşitleme sürümünü doğrulayın.

  3. Bir sonraki seferde kullanacağınız sürümü elde etmek için CHANGE_TRACKING_CURRENT_VERSION() kullanın.

  4. Sales kullanarak CHANGETABLE(CHANGES ...) tablosundaki değişiklikleri elde etme

  5. SalesOrders kullanarak CHANGETABLE(CHANGES ...) tablosundaki değişiklikleri elde etme

  6. İşlemi işleme.

Değişiklikleri edinmenin tüm adımları anlık görüntü işleminin içinde olduğundan anımsamanız gereken bazı noktalar:

  • Son eşitleme sürümü doğrulandıktan sonra temizleme işlemi gerçekleşirse, temizleme tarafından gerçekleştirilen silme işlemleri işlemin içinde görünmeyeceği için, CHANGETABLE(CHANGES ...) sonuçları geçerliliğini korur.

  • Bir sonraki eşitleme sürümü alındıktan sonra Sales tablosunda veya SalesOrders tablosunda yapılan değişiklikler görünmez ve CHANGETABLE(CHANGES ...) çağrıları hiçbir zaman CHANGE_TRACKING_CURRENT_VERSION() tarafından döndürülen sürümden daha sonraki bir değişiklik sürümünü döndürmez. Çağrıların arasındaki süre içinde işlenen işlemler görünür olmayacağından, Sales ile SalesOrders arasındaki CHANGETABLE(CHANGES ...) tutarlılık da korunur.

Aşağıdaki örnekte bir veritabanı için anlık görüntü yalıtımının nasıl etkinleştirildiği gösterilmektedir.

-- The database must be configured to enable snapshot isolation.
ALTER DATABASE AdventureWorksLT
    SET ALLOW_SNAPSHOT_ISOLATION ON;

Anlık görüntü işlemi aşağıdaki gibi kullanılır:

SET TRANSACTION ISOLATION LEVEL SNAPSHOT;
BEGIN TRAN
  -- Verify that version of the previous synchronization is valid.
  -- Obtain the version to use next time.
  -- Obtain changes.
COMMIT TRAN

Anlık görüntü işlemleri hakkında daha fazla bilgi için bkz. SET TRANSACTION ISOLATION LEVEL (Transact-SQL).

Temizleme ve anlık görüntü yalıtımı

Aynı veritabanında veya aynı örnekteki iki farklı veritabanında hem anlık görüntü yalıtımının hem de değişiklik izlemenin etkinleştirilmesi, veritabanında anlık görüntü yalıtımı olan açık bir işlem olduğunda temizleme işleminin süresi dolan satırları sys.syscommittab bırakmasına neden olabilir. Bu durum, değişiklik izleme temizleme işlemi sırasında sistem genelinde kullanılan düşük su seviyesi işaretçisi (bu, güvenli temizleme sürümünü temsil eder) hesaba katıldığında oluşabilir. Bu işlem, değişiklik izleme otomatik temizleme sürecinin, anlık görüntü yalıtımı etkinleştirilmiş veritabanındaki açık işlemin ihtiyaç duyabileceği satırları kaldırmamasını sağlamak için yapılır. sys.syscommittab süresi dolan satırların zamanında temizlendiğinden emin olmak için, kaydedilmiş anlık görüntü yalıtımını ve anlık görüntü yalıtım işlemlerini mümkün olduğunca kısa tutun.

Anlık görüntü yalıtımına alternatifler

Anlık görüntü yalıtımı kullanmanın alternatifleri vardır, ancak tüm uygulama gereksinimlerinin karşılandığından emin olmak için daha fazla çalışma gerektirir. Değişiklikler alınmadan önce last_synchronization_version'nin geçerli ve verilerin temizleme işlemiyle kaldırılmadığından emin olmak için şu adımları izleyin:

  1. last_synchronization_version çağrılarına CHANGETABLE()sonra denetleyin.

  2. Her sorgunun parçası olarak last_synchronization_version kullanarak değişiklikleri almak için CHANGETABLE() kontrol edin.

Değişiklikler, bir sonraki numaralandırma için senkronizasyon sürümü alındıktan sonra oluşabilir. Bu durumu halletmenin iki yolu vardır. Kullanılan seçenek uygulamaya ve her yaklaşımın yan etkilerini nasıl işleyebileceğine bağlıdır:

  • Yeni eşitleme sürümünden daha büyük sürümlere sahip değişiklikleri yoksayın.

    Bu yaklaşımın yan etkisi, yeni bir eşitleme sürümünden önce oluşturulmuş veya güncellenmiş bir satırın, daha sonra güncellenmişse atlanmasıdır. Eğer atlanan satıra başvuran başka bir tabloda oluşturulmuş bir satır varsa, yeni bir satır oluşması referans bütünlüğü sorunu yaratabilir. Güncellenmiş bir satır varsa, satır atlanır ve bir sonraki seferine kadar eşitlenmez.

  • Yeni eşitleme sürümünden daha büyük bir sürüme sahip olanlar dahil olmak üzere tüm değişiklikleri dahil edin.

    Yeni eşitleme sürümünden daha büyük bir sürüme sahip olan satırlar bir sonraki eşitlemede yeniden elde edilir. Beklenen bir durum ve uygulama tarafından işlenmesi gereken bir durum olmalıdır.

Önceki iki seçeneğe ek olarak, işleme bağlı olarak her iki seçeneği de birleştiren bir yaklaşım oluşturabilirsiniz. Örneğin, satırın oluşturulduğu veya silindiği bir sonraki eşitleme sürümünden daha yeni olan değişiklikleri yoksaymanın en iyi olduğu, ancak güncellemelerin yoksayılmadığı bir uygulama isteyebilirsiniz.

Not

Değişiklik izleme (veya herhangi bir özel izleme mekanizması) kullanırken uygulama için çalışacak yaklaşımın seçilmesi önemli bir analiz gerektirir. Bu nedenle, anlık görüntü yalıtımını kullanmak çok daha kolaydır.

Değişiklik izleme, veritabanındaki değişiklikleri nasıl işler?

Değişiklik izleme kullanan bazı uygulamalar başka bir veri deposuyla iki yönlü eşitleme gerçekleştirir. Diğer bir deyişle, SQL Server veritabanında yapılan değişiklikler diğer veri deposunda güncelleştirilir ve diğer depoda yapılan değişiklikler SQL Server veritabanında güncelleştirilir.

Bir uygulama yerel veritabanını başka bir veri deposundaki değişikliklerle güncelleştirdiğinde, uygulamanın aşağıdaki işlemleri gerçekleştirmesi gerekir:

  • Çakışmaları denetleyin.

    Her iki veri deposunda da aynı veriler aynı anda değiştirildiğinde çakışma oluşur. Uygulamanın çakışma olup olmadığını denetleyebilmesi ve çakışmanın çözülmesini sağlamak için yeterli bilgi edinebilmesi gerekir.

  • Uygulama bağlam bilgilerini depolayın.

    Uygulama, değişiklik izleme bilgilerine sahip verileri depolar. Bu bilgiler, yerel veritabanından değişiklikler elde edildiğinde diğer değişiklik izleme bilgileriyle birlikte kullanılabilir. Bu bağlamsal bilgilerin yaygın bir örneği, değişikliğin kaynağı olan veri deposunun tanımlayıcısıdır.

Önceki işlemleri gerçekleştirmek için bir eşitleme uygulaması aşağıdaki işlevleri kullanabilir:

  • CHANGETABLE(VERSION...)

    Bir uygulama değişiklik yaparken çakışmaları denetlemek için bu işlevi kullanabilir. İşlev, izlenen bir değişiklik tablosunda belirtilen satır için en son değişiklik izleme bilgilerini alır. Değişiklik izleme bilgileri, satırın son değiştirilen sürümünü içerir. Bu bilgiler bir uygulamanın, uygulamanın son eşitlenmesinden sonra satırın değiştirilip değiştirilmediğini belirlemesini sağlar.

  • WITH CHANGE_TRACKING_CONTEXT

    Bir uygulama bağlam verilerini depolamak için bu yan tümceyi kullanabilir.

Çakışmaları denetleme

İki yönlü eşitleme senaryosunda, istemci uygulamasının, uygulamanın değişiklikleri en son edindiğinden bu yana bir satırın güncelleştirilip güncelleştirilmediğini belirlemesi gerekir.

Aşağıdaki örnekte, çakışmaları ayrı bir sorgu olmadan en verimli şekilde denetlemek için işlevinin nasıl kullanılacağı CHANGETABLE(VERSION ...) gösterilmektedir. Örnekte, CHANGETABLE(VERSION ...)SYS_CHANGE_VERSIONtarafından belirtilen satırın @product id belirler. CHANGETABLE(CHANGES ...) aynı bilgileri edinebilir, ancak bu daha az verimli olur. Satır için SYS_CHANGE_VERSION değeri @last_sync_versiondeğerinden büyükse çakışma olur. Çakışma olursa satır güncelleştirilmez. Satır için değişiklik bilgisi olmayabileceğinden ISNULL() denetimi gereklidir. Değişiklik izleme etkinleştirildikten sonra veya değişiklik bilgileri temizlendikten sonra satır güncelleştirilmeseydi değişiklik bilgisi mevcut olmazdı.

-- Assumption: @last_sync_version has been validated.
UPDATE SalesLT.Product
SET ListPrice = @new_listprice
FROM SalesLT.Product AS P
WHERE ProductID = @product_id
    AND @last_sync_version >= ISNULL((
            SELECT CT.SYS_CHANGE_VERSION
            FROM CHANGETABLE(VERSION SalesLT.Product, (ProductID), (P.ProductID)) AS CT
            ), 0);

Aşağıdaki kod güncelleştirilmiş satır sayısını denetleyebilir ve çakışma hakkında daha fazla bilgi tanımlayabilir.

-- If the change cannot be made, find out more information.
IF (@@ROWCOUNT = 0)
BEGIN
    -- Obtain the complete change information for the row.
    SELECT
        CT.SYS_CHANGE_VERSION, CT.SYS_CHANGE_CREATION_VERSION,
        CT.SYS_CHANGE_OPERATION, CT.SYS_CHANGE_COLUMNS
    FROM
        CHANGETABLE(CHANGES SalesLT.Product, @last_sync_version) AS CT
    WHERE
        CT.ProductID = @product_id;

    -- Check CT.SYS_CHANGE_VERSION to verify that it really was a conflict.
    -- Check CT.SYS_CHANGE_OPERATION to determine the type of conflict:
    -- update-update or update-delete.
    -- The row that is specified by @product_id might no longer exist 
    -- if it has been deleted.
END

Bağlam bilgilerini ayarlama

yan tümcesini WITH CHANGE_TRACKING_CONTEXT kullanarak bir uygulama, bağlam bilgilerini değişiklik bilgileriyle birlikte depolayabilir. Bu bilgiler daha sonra SYS_CHANGE_CONTEXT tarafından döndürülen CHANGETABLE(CHANGES ...) sütunundan alınabilir.

Bağlam bilgileri genellikle değişikliklerin kaynağını tanımlamak için kullanılır. Değişikliğin kaynağı tanımlanabiliyorsa, bu bilgiler yeniden eşitlendiğinde değişiklikleri almaktan kaçınmak için veri deposu tarafından kullanılabilir.

-- Try to update the row and check for a conflict.
WITH CHANGE_TRACKING_CONTEXT (@source_id)
UPDATE
  SalesLT.Product
SET
  ListPrice = @new_listprice
FROM
  SalesLT.Product AS P
WHERE
  ProductID = @product_id AND
    @last_sync_version >= ISNULL (
    (SELECT CT.SYS_CHANGE_VERSION FROM CHANGETABLE(VERSION SalesLT.Product,
    (ProductID), (P.ProductID)) AS CT),
       0);

Tutarlı ve doğru sonuçlar elde edin

Bir uygulama, @last_sync_versiondeğerini doğruladığında temizleme işlemini dikkate almalıdır. Bunun nedeni, CHANGE_TRACKING_MIN_VALID_VERSION() çağrıldıktan sonra ancak güncelleştirme yapılmadan önce verilerin kaldırılmış olabilmesidir.

Anlık görüntü yalıtımını kullanmanız ve değişiklikleri anlık görüntü işlemi içinde yapmanız gerekir.

-- Prerequisite is to ensure ALLOW_SNAPSHOT_ISOLATION is ON for the database.

SET TRANSACTION ISOLATION LEVEL SNAPSHOT;
BEGIN TRAN
    -- Verify that last_sync_version is valid.
    IF (@last_sync_version <
CHANGE_TRACKING_MIN_VALID_VERSION(OBJECT_ID('SalesLT.Product')))
    BEGIN
       RAISERROR (N'Last_sync_version too old', 16, -1);
    END
    ELSE
    BEGIN
        -- Try to update the row.
        -- Check @@ROWCOUNT and check for a conflict.
    END;
COMMIT TRAN;

Not

Anlık görüntü işlemi başlatıldıktan sonra, anlık görüntü işlemi içinde güncelleştirilen satırın başka bir işlemde güncelleştirilmiş olma olasılığı vardır. Bu durumda bir anlık görüntü yalıtımı güncelleştirme çakışması oluşur ve işlemin sonlandırılmasıyla sonuçlanır. Böyle bir durumda güncelleştirmeyi yeniden deneyin. Böylece bir değişiklik izleme çakışması algılanır ve hiçbir satır değiştirilmez.

Değişiklik izleme ve veri geri yükleme

Eşitleme gerektiren uygulamalar, değişiklik izleme özelliği etkin olan bir veritabanının verilerin önceki bir sürümüne döndürülme durumunu dikkate almalıdır. Bu durum, veritabanı yedekten geri yüklendikten sonra, zaman uyumsuz veritabanı yansıtmasına geçiş yapıldığında veya günlük gönderimi kullanılırken bir hata oluştuğunda ortaya çıkabilir. Aşağıdaki senaryoda sorun gösterilmektedir:

  1. T1 tablosu değişiklikler izlenir ve tablo için en düşük geçerli sürüm 50'dir.

  2. İstemci uygulaması 100 sürümündeki verileri eşitler ve sürüm 50 ile 100 arasındaki tüm değişiklikler hakkında bilgi alır.

  3. 100 sürümünden sonra T1 tablosunda ek değişiklikler yapılır.

  4. Sürüm 120'de bir hata vardır ve veritabanı yöneticisi veritabanını veri kaybıyla geri yükler. Geri yükleme işleminden sonra, tablo sürüm 70'e kadar olan verileri içerir ve eşitlenen en düşük sürüm hala 50'dir.

    Bu, eşitlenen veri deposunun artık birincil veri deposunda bulunmayan verilere sahip olduğu anlamına gelir.

  5. T1 birçok kez güncelleştirilir. Bu, geçerli sürümü 130'a getirir.

  6. İstemci uygulaması yeniden senkronize edilir ve en son senkronize edilen sürüm numarası 100 olan sürümü sağlar. 100 değeri 50'den büyük olduğundan istemci bu sayıyı başarıyla doğrular.

    İstemci, sürüm 100 ile 130 arasındaki değişiklikleri alır. Bu noktada istemci, 70 ile 100 arasındaki değişikliklerin öncekiyle aynı olmadığının farkında değildir. İstemci ve sunucudaki veriler eşitlenmez.

Veritabanı 100 sürümünden sonraki bir noktaya kurtarıldıysa eşitlemeyle ilgili bir sorun olmaz. İstemci ve sunucu, sonraki eşitleme aralığında verileri doğru şekilde eşitler.

Değişiklik izleme, veri kaybından kurtarma desteği sağlamaz. Ancak, bu tür eşitleme sorunlarını algılamak için iki seçenek vardır:

  • Sunucuda bir veritabanı sürüm kimliği depolayın ve bir veritabanı kurtarıldıysa veya başka bir şekilde veri kaybettiğinde bu değeri güncelleştirin. Her istemci uygulaması kimliği depolar ve her istemcinin verileri eşitlerken bu kimliği doğrulaması gerekir. Veri kaybı oluşursa kimlikler eşleşmez ve istemciler yeniden başlatılır. Veri kaybının son eşitlenen sınırı aşmamış olması, istemcinin gereksiz bir yeniden başlatma gerçekleştirmesi bir dezavantajdır.

  • bir istemci değişiklikleri sorguladığında, sunucudaki her istemci için son eşitleme sürüm numarasını kaydedin. Verilerle ilgili bir sorun varsa, son eşitlenen sürüm numaraları eşleşmez. Bu, yeniden başlatma gerektiğini gösterir.