Welcome to Sign in | Help

Re: SQL 2000 - SNAPSHOT ISOLATION

  •  12-06-2009, 4:12 PM

    Re: SQL 2000 - SNAPSHOT ISOLATION

    ALLOW_SNAPSHOT_ISOLATION a fost introdus începând cu SQL 2005.

    Totuşi dacă BD este SQL2005(2008 ?) şi setezi nivelul de compatibilitate la SQL2000 poţi utiliza acest nivel de izolare a tranzacţiilor. Citeşte şi comentariile.

    A doua opţiune ar fi să implementezi chiar tu acest nivel de izolare.
    O posibilă soluţie în acest sens ar putea fi (scripturile 2 şi 3 tb. rulate în ferestre separate SSMS/"în paralel"):
    Angel Script T-SQL 1
    IF OBJECT_ID('Marbles') IS NOT NULL
      DROP TABLE Marbles;
    GO

    CREATE TABLE Marbles
    (
    ID INT PRIMARY KEY,
    Color VARCHAR(10) NOT NULL
    );
    GO

    INSERT INTO Marbles VALUES (1, 'Black');
    INSERT INTO Marbles VALUES (2, 'White');
    GO

    SELECT * FROM Marbles


    Beer Script T-SQL 2
    BEGIN TRAN
      DECLARE @temp TABLE (ID INT PRIMARY KEY, Color VARCHAR(10) NOT NULL)
      INSERT INTO @temp
      SELECT *
      FROM Marbles
      WHERE Color = 'Black'
      
      
      WAITFOR DELAY '00:00:10'
      UPDATE @temp SET Color = 'White'
      UPDATE Marbles SET Color = TMP.Color FROM @temp AS TMP WHERE Marbles.ID = TMP.ID
    COMMIT TRAN
    PRINT 'Finish T1'

    SELECT * FROM Marbles

    Coffee Script T-SQL 3
    BEGIN TRAN
      DECLARE @temp TABLE (ID INT PRIMARY KEY, Color VARCHAR(10) NOT NULL)
      INSERT INTO @temp
      SELECT *
      FROM Marbles
      WHERE Color = 'White'
      
      
      WAITFOR DELAY '00:00:20'
      UPDATE @temp SET Color = 'Black'
      UPDATE Marbles SET Color = TMP.Color FROM @temp AS TMP WHERE Marbles.ID = TMP.ID
    COMMIT TRAN
    PRINT 'Finish T2'

    SELECT * FROM Marbles

    Iniţial am:
    ID    Color
    1    Black
    2    White

    Rezultatul este:
    ID    Color
    1    White
    2    Black

    şi NU
    1    White
    2    White
    sau
    1    Black
    2    Black

    După cum se observă, ideea este ca la începutul fiecărei tranzacţii se încarcă înregistrările într-un cache (@temp) şi toate modificările care le realizăm, nu se fac direct pe tabela Marbles ci în cache. La finalul tranzacţiei actualizez tabela Marbles cu modificările din cache-ul fiecărei tranzacţii folosind  valorile din cheia primară.

    Soluţia aceasta nu este 100% . Dacă cea de-a doua tranzacţie citeşte (INSERT ... SELECT) date din Marbles între ultimul UPDATE şi COMMIT de la prima tranzacţie:
      UPDATE Marbles SET Color = TMP.Color FROM @temp AS TMP WHERE Marbles.ID = TMP.ID
      --- aici T2 citeste datele cu INSERT ... SELECT ... ---
    COMMIT TRAN

    atunci vei avea o problemă.

    PS: Alte informaţii utile pot fi găsite aici.
View Complete Thread
Powered by Community Server (Commercial Edition), by Telligent Systems