Udostępnij przez


Row Versioning-based Isolation Level Example

Następujące przykłady przedstawiają różnice w zachowaniu między migawka izolacji transakcji oraz transakcje zatwierdzone odczytu za pomocą wersji wiersza.

Uwaga

Ważne jest zrozumieć poziomów izolacji na przechowywanie wersji wiersza przed przeglądając poniższe przykłady.Zobacz Understanding Row Versioning-Based Isolation Levels i Za pomocą wiersza oparte na wersji poziomy izolacji.

Przykłady

A.Praca z izolacji migawka

W tym przykładzie działająca w ramach migawka izolacji transakcji odczytuje dane, które zostanie następnie zmodyfikowany przez inną transakcję.Transakcja migawka operacji aktualizacji, wykonywany przez inne transakcje nie są blokowane, a nadal odczytywać dane z wersji wiersza, ignorując modyfikacji danych.Jednak podczas transakcji migawka usiłuje zmodyfikować dane, które już został zmodyfikowany przez inne transakcje, transakcja migawka generuje błąd i jest przerywane.

W sesja 1:

USE AdventureWorks;
GO

-- Enable snapshot isolation on the database.
ALTER DATABASE AdventureWorks
    SET ALLOW_SNAPSHOT_ISOLATION ON;
GO

-- Start a snapshot transaction
SET TRANSACTION ISOLATION LEVEL SNAPSHOT;
GO

BEGIN TRANSACTION;
    -- This SELECT statement will return
    -- 48 vacation hours for the employee.
    SELECT EmployeeID, VacationHours
        FROM HumanResources.Employee
        WHERE EmployeeID = 4;

W sesja 2:

USE AdventureWorks;
GO

-- Start a transaction
BEGIN TRANSACTION;
    -- Subtract a vacation day from employee 4.
    -- Update is not blocked by session 1 since
    -- under snapshot isolation shared locks are
    -- not requested.
    UPDATE HumanResources.Employee
        SET VacationHours = VacationHours - 8
        WHERE EmployeeID = 4;

-- Verify that the employee now has 40 vacation hours.
    SELECT VacationHours
        FROM HumanResources.Employee
        WHERE EmployeeID = 4;

W sesja 1:

    -- Reissue the SELECT statement - this shows
    -- the employee having 48 vacation hours.  The
    -- snapshot transaction is still reading data from
    -- the versioned row.
SELECT EmployeeID, VacationHours
        FROM HumanResources.Employee
        WHERE EmployeeID = 4;

W sesja 2:

-- Commit the transaction; this commits the data
-- modification.
COMMIT TRANSACTION;
GO

W sesja 1:

    -- Reissue the SELECT statement - this still 
    -- shows the employee having 48 vacation hours
    -- even after the other transaction has committed
    -- the data modification.
SELECT EmployeeID, VacationHours
        FROM HumanResources.Employee
        WHERE EmployeeID = 4;

    -- Because the data has been modified outside of the
    -- snapshot transaction, any further data changes to 
    -- that data by the snapshot transaction will cause 
    -- the snapshot transaction to fail. This statement 
    -- will generate a 3960 error and the transaction will 
    -- terminate.
    UPDATE HumanResources.Employee
        SET SickLeaveHours = SickLeaveHours - 8
        WHERE EmployeeID = 4;

-- Undo the changes to the database from session 1. 
-- This will not undo the change from session 2.
ROLLBACK TRANSACTION
GO

B.Praca z popełnionych odczytu przy użyciu wersji wiersza

W tym przykładzie popełnionych odczytu transakcji za pomocą wersji wiersza działa równolegle z inną transakcję.Transakcja przekazana odczytu zachowuje się inaczej niż transakcji migawka.Transakcja migawka, takie jak transakcja przekazana odczytu odczyta wersji wierszy nawet po innych transakcji zostało zmodyfikowane dane.Jednak w przeciwieństwie do transakcji migawka, transakcja przekazana odczytu będzie:

  • Przeczytaj zmodyfikowane dane po innych transakcji zatwierdza zmiany danych.

  • Można aktualizować dane zmodyfikowane przez inne transakcje w przypadku gdy transakcja migawka nie.

W sesja 1:

USE AdventureWorks;
GO

-- Enable READ_COMMITTED_SNAPSHOT on the database.
-- For this statement to succeed, this session
-- must be the only connection to the AdventureWorks
-- database.
ALTER DATABASE AdventureWorks
    SET READ_COMMITTED_SNAPSHOT ON;
GO

-- Start a read-committed transaction
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
GO

BEGIN TRANSACTION;
    -- This SELECT statement will return
    -- 48 vacation hours for the employee.
    SELECT EmployeeID, VacationHours
        FROM HumanResources.Employee
        WHERE EmployeeID = 4;

W sesja 2:

USE AdventureWorks;
GO

-- Start a transaction
BEGIN TRANSACTION;
    -- Subtract a vacation day from employee 4.
    -- Update is not blocked by session 1 since
    -- under read-committed using row versioning shared locks are
    -- not requested.
    UPDATE HumanResources.Employee
        SET VacationHours = VacationHours - 8
        WHERE EmployeeID = 4;

-- Verify that the employee now has 40 vacation hours.
    SELECT VacationHours
        FROM HumanResources.Employee
        WHERE EmployeeID = 4;

W sesja 1:

    -- Reissue the SELECT statement - this still shows
    -- the employee having 48 vacation hours.  The
    -- read-committed transaction is still reading data 
    -- from the versioned row and the other transaction 
    -- has not committed the data changes yet.
SELECT EmployeeID, VacationHours
        FROM HumanResources.Employee
        WHERE EmployeeID = 4;

W sesja 2:

-- Commit the transaction
COMMIT TRANSACTION;
GO

W sesja 1:

    -- Reissue the SELECT statement which now shows the 
    -- employee having 40 vacation hours.  Being 
    -- read-committed, this transaction is reading the 
    -- committed data.  This is different from snapshot
    -- isolation which reads from the versioned row.
    SELECT EmployeeID, VacationHours
        FROM HumanResources.Employee
        WHERE EmployeeID = 4;

    -- This statement, which caused the snapshot transaction 
    -- to fail, will succeed with read-committed using row versioning.
    UPDATE HumanResources.Employee
        SET SickLeaveHours = SickLeaveHours - 8
        WHERE EmployeeID = 4;

-- Undo the changes to the database from session 1. 
-- This will not undo the change from session 2.
ROLLBACK TRANSACTION;
GO