Beispiel für eine auf der Zeilenversionsverwaltung basierende Isolationsstufe

Die folgenden Beispiele zeigen die Unterschiede im Verhalten zwischen Snapshotisolationstransaktionen und Transaktionen, bei denen ein Commit vor dem Lesevorgang ausgeführt werden muss, und die die Zeilenversionsverwaltung verwenden.

ms191190.note(de-de,SQL.90).gifHinweis:
Sie müssen sich mit auf der Zeilenversionsverwaltung basierenden Isolationsstufen vertraut gemacht haben, bevor Sie die folgenden Beispiele durcharbeiten. Siehe Grundlegendes zu zeilenversionsbasierten Isolationsstufen und Verwenden von auf Zeilenversionsverwaltung basierenden Isolationsstufen.

Beispiele

A. Arbeiten mit Snapshotisolation

In diesem Beispiel liest eine Transaktion, die unter Snapshotisolation ausgeführt wird, Daten, die anschließend von einer anderen Transaktion geändert werden. Die Snapshottransaktion blockiert nicht die Aktualisierungsoperation, die von der anderen Transaktion ausgeführt wird, liest auch weiterhin Daten aus der versionsspezifischen Zeile und ignoriert die Datenänderung. Wenn die Snapshottransaktion jedoch versucht, die Daten zu ändern, die bereits von der anderen Transaktion geändert wurden, generiert die Snapshottransaktion einen Fehler und wird beendet.

Für Sitzung 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;

Für Sitzung 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;

Für Sitzung 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;

Für Sitzung 2:

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

Für Sitzung 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. Arbeiten mit Transaktionen, bei denen ein Commit vor dem Lesevorgang ausgeführt werden muss, und der Zeilenversionsverwaltung

In diesem Beispiel wird eine Transaktion, bei der ein Commit vor dem Lesevorgang ausgeführt werden muss und die Zeilenversionsverwaltung verwendet wird, gleichzeitig mit einer anderen Transaktion ausgeführt. Die Transaktion, bei der ein Commit vor dem Lesevorgang ausgeführt werden muss, verhält sich anders als eine Snapshottransaktion. Ebenso wie eine Snapshottransaktion liest die Transaktion, bei der ein Commit vor dem Lesevorgang ausgeführt werden muss, versionsspezifische Zeilen, nachdem die andere Transaktion Daten geändert hat. Im Gegensatz zu einer Snapshottransaktion gilt für die Transaktion, bei der ein Commit vor dem Lesevorgang ausgeführt werden muss, jedoch Folgendes:

  • Sie liest die geänderten Daten, nachdem die andere Transaktion ein Commit der Datenänderungen vorgenommen hat.
  • Sie ist in der Lage, die von der anderen Transaktion bearbeiteten Daten zu aktualisieren, was der Snapshottransaktion nicht möglich ist.

Für Sitzung 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;

Für Sitzung 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;

Für Sitzung 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;

Für Sitzung 2:

-- Commit the transaction
COMMIT TRANSACTION;
GO

Für Sitzung 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

Siehe auch

Konzepte

Grundlegendes zu zeilenversionsbasierten Isolationsstufen
Auswählen von auf Zeilenversionsverwaltung basierenden Isolationsstufen
Transaktionen (Datenbankmodul)
Verwenden von auf Zeilenversionsverwaltung basierenden Isolationsstufen

Andere Ressourcen

Auf Zeilenversionsverwaltung basierende Isolationsstufen im Datenbankmodul

Hilfe und Informationen

Informationsquellen für SQL Server 2005