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