Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
In vielen Szenarien müssen Sie die Transaktionsisolationsstufe angeben. Transaktionsisolation für speicheroptimierte Tabellen unterscheidet sich von datenträgerbasierten Tabellen.
Anforderungen für die Angabe der Transaktionsisolationsstufe:
TRANSACTION ISOLATION LEVEL ist eine erforderliche Option für den ATOMIC-Block, der den Inhalt einer nativ kompilierten gespeicherten Prozedur umfasst.
Aufgrund von Einschränkungen bei der Verwendung von Isolationsstufen in containerübergreifenden Transaktionen müssen speicheroptimierte Tabellen in interpretierten Transact-SQL häufig von einem Tabellenhinweis begleitet werden, der die für den Zugriff auf die Tabelle verwendete Isolationsstufe angibt. Weitere Informationen zu Hinweisen auf Isolationsstufe und containerübergreifenden Transaktionen finden Sie unter Transaktionsisolationsstufen.
Die gewünschte Transaktionsisolationsstufe muss explizit deklariert werden. Es ist nicht möglich, Sperrhinweise (z. B. XLOCK) zu verwenden, um die Isolierung bestimmter Zeilen oder Tabellen in der Transaktion zu gewährleisten.
Die Anwendung, die auf die Datenbank zugreift, sollte Wiederholungslogik implementieren, um Fehler zu behandeln, die sich aus Transaktionsverhängungskonflikten, Validierungsfehlern und Commit-Abhängigkeitsfehlern ergeben. Beachten Sie, dass Fehler durch Commit-Abhängigkeiten auch bei schreibgeschützten Transaktionen auftreten können.
Lange ausgeführte Transaktionen sollten mit speicheroptimierten Tabellen vermieden werden. Solche Transaktionen erhöhen die Wahrscheinlichkeit von Konflikten und nachfolgenden Transaktionsbeendigungen. Eine lang andauernde Transaktion verschiebt auch die Speicherbereinigung. Je länger eine Transaktion ausgeführt wird, desto länger behält In-Memory OLTP kürzlich gelöschte Zeilenversionen bei, was die Suchleistung für neue Transaktionen verringern kann.
Datenträgerbasierte Tabellen basieren in der Regel auf sperren und blockieren für die Transaktionsisolation. Speicheroptimierte Tabellen basieren auf mehrstufiger Versionsverwaltung und Konflikterkennung, um eine Isolation zu gewährleisten. Ausführliche Informationen finden Sie im Abschnitt "Konflikterkennungs-, Validierungs- und Commit-Abhängigkeitsüberprüfungen in Transaktionen in Memory-Optimized Tabellen".
Datenträgerbasierte Tabellen erlauben Multiversioning mit den Isolationsstufen SNAPSHOT und READ_COMMITTED_SNAPSHOT. Für speicheroptimierte Tabellen sind alle Isolationsebenen mehrversionsbasiert, einschließlich REPEATABLE READ und SERIALIZABLE.
Arten von Transaktionen
Jede Abfrage in SQL Server wird im Kontext einer Transaktion ausgeführt.
Es gibt drei Arten von Transaktionen in SQL Server:
AutoCommit-Transaktionen. Wenn in der Sitzung kein aktiver Transaktionskontext vorhanden ist und implizite Transaktionen nicht auf EIN festgelegt sind, verfügt jede Abfrage über einen eigenen Transaktionskontext. Die Transaktion beginnt, wenn die Anweisung mit der Ausführung beginnt, und wird abgeschlossen, wenn die Anweisung abgeschlossen ist.
Explizite Transaktionen. Der Benutzer startet die Transaktion über einen expliziten BEGIN TRAN oder BEGIN ATOMIC. Die Transaktion wird nach dem entsprechenden COMMIT und ROLLBACK oder END (bei einem Atomblock) abgeschlossen.
Implizite Transaktionen. Wenn die Option IMPLICIT_TRANSACTIONS auf EIN festgelegt ist, wird eine Transaktion implizit gestartet, wenn der Benutzer eine Anweisung ausführt und kein aktiver Transaktionskontext vorhanden ist. Die Transaktion wird durch einen expliziten COMMIT und ROLLBACK abgeschlossen.
Geplante READ COMMIT-Isolation
READ COMMITTED ist die Standardisolationsstufe in Microsoft SQL Server.
Die Isolationsstufe READ COMMITTED garantiert, dass Transaktionen keine nicht freigegebenen Daten von Änderungen außerhalb der aktuellen Transaktion sehen. Mit anderen Worten, die Transaktion liest nur Daten, die entweder in die Datenbank übernommen wurden oder von der aktuellen Transaktion geändert worden sind.
Alle Isolationsstufen, die für speicheroptimierte Tabellen unterstützt werden, bieten die Leseverzichtsgarantie. Wenn für die Transaktion keine stärkeren Garantien erforderlich sind, können Sie daher alle Isolationsstufen verwenden, die für speicheroptimierte Tabellen unterstützt werden. SNAPSHOT verwendet die wenigen Systemressourcen im Vergleich zu anderen Isolationsstufen.
Die Garantie der SNAPSHOT-Isolationsebene (die niedrigste Isolationsstufe, die für speicheroptimierte Tabellen unterstützt wird) umfasst die Garantien von READ COMMITTED. Jede Anweisung in der Transaktion liest dieselbe, konsistente Version der Datenbank. Nicht nur werden alle von der Transaktion gelesenen Zeilen in die Datenbank übergeben, sondern auch alle Lesevorgänge erfassen die Änderungen, die von derselben Gruppe von Transaktionen vorgenommen wurden.
Richtlinie: Wenn nur die READ COMMIT-Isolationsgarantie erforderlich ist, verwenden Sie die SNAPSHOT-Isolation mit nativ kompilierten gespeicherten Prozeduren und für den Zugriff auf speicheroptimierte Tabellen über interpretierte Transact-SQL.
Bei Autocommit-Transaktionen wird die Isolationsebene READ COMMITTED für speicheroptimierte Tabellen implizit auf SNAPSHOT abgebildet. Wenn die Sitzungseinstellung TRANSACTION ISOLATION LEVEL auf READ COMMITTED festgelegt ist, ist es daher nicht erforderlich, die Isolationsstufe über einen Tabellenhinweis beim Zugriff auf speicheroptimierte Tabellen anzugeben.
Das folgende Beispiel für eine Autocommit-Transaktion zeigt eine Verknüpfung zwischen einer speicheroptimierten Tabelle "Kunden" und einer regulären Tabelle [Bestellverlauf], als Teil eines Ad-hoc-Batches:
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
GO
SELECT *
FROM dbo.Customers AS c
LEFT JOIN dbo.[Order History] AS oh
ON c.customer_id = oh.customer_id;
Das folgende Beispiel für explizite oder implizite Transaktionen zeigt denselben Join, aber dieses Mal in einer expliziten Benutzertransaktion. Auf die speicheroptimierte Tabelle "Customers" wird unter Momentaufnahmeisolation zugegriffen, wie durch den Tabellenhinweis WITH (SNAPSHOT) angegeben, und auf die reguläre Tabelle [Bestellverlauf] wird unter lesesicherer Isolation zugegriffen:
SET TRANSACTION ISOLATION LEVEL READ COMMITTED
GO
BEGIN TRAN
SELECT * FROM dbo.Customers c with (SNAPSHOT)
LEFT JOIN dbo.[Order History] oh
ON c.customer_id=oh.customer_id
...
COMMIT
Operative Unterschiede
Neben der Lesend-Beständig-Garantie gibt es auch zwei wichtige Implementierungsdetails, auf die sich Anwendungen, die Datenträgerbasierte Tabellen verwenden, stützen können. Beachten Sie Folgendes beim Konvertieren einer datenträgerbasierten Tabelle, auf die mithilfe der READ COMMIT-Isolation zu einer speicheroptimierten Tabelle zugegriffen wird, auf die mithilfe der SNAPSHOT-Isolation zugegriffen wird:
Die Implementierung der READ COMMITTED-Isolationsstufe für datenträgerbasierte Tabellen (vorausgesetzt, READ_COMMITTED_SNAPSHOT ausgeschaltet ist) verwendet Sperrungen, um Konflikte zwischen Lesern und Schreibern zu verhindern. Wenn ein Writer mit dem Aktualisieren einer Zeile beginnt, nimmt er eine Sperre und gibt die Sperre erst wieder frei, wenn die Transaktion bestätigt wurde. Alle Lesevorgänge werden blockiert und warten, bis die Schreibtransaktion committet wird.
Einige Anwendungen gehen möglicherweise davon aus, dass Leser immer darauf warten, dass Autoren sich verpflichten, insbesondere, wenn eine Synchronisierung zwischen den beiden Transaktionen auf der Anwendungsebene vorhanden ist.
Richtlinie: Anwendungen können sich nicht auf das Blockierungsverhalten verlassen. Wenn eine Anwendung eine Synchronisierung zwischen gleichzeitigen Transaktionen benötigt, kann diese Logik auf der Anwendungsebene oder in der Datenbankebene über sp_getapplock (Transact-SQL) implementiert werden.
Bei Transaktionen, die die READ COMMITTED-Isolation verwenden, sieht jede Anweisung die neueste Version der Zeilen in der Datenbank. Daher bewirken nachfolgende Abfragen Änderungen im Zustand der Datenbank.
Das Abrufen einer Tabelle mithilfe einer WHILE-Schleife, bis eine neue Zeile gefunden wurde, ist ein Beispiel für ein Anwendungsmuster, das diese Annahme verwendet. Bei jeder Iteration der Schleife werden in der Abfrage die neuesten Aktualisierungen in der Datenbank angezeigt.
Richtlinie: Wenn eine Anwendung eine speicheroptimierte Tabelle abrufen muss, um die neuesten Zeilen abzurufen, die in die Tabelle geschrieben wurden, verschieben Sie die Abrufschleife außerhalb des Transaktionsbereichs.
Es folgt ein Beispiel für ein Anwendungsmuster, das diese Annahme verwendet. Abrufen einer Tabelle mithilfe einer WHILE-Schleife, bis eine neue Zeile gefunden wird. In jeder Schleifeniteration greift die Abfrage auf die neuesten Aktualisierungen in der Datenbank zu.
Das folgende Beispielskript fragt eine Tabelle t1 ab, bis sie eine Zeile enthält. Anschließend wird eine einzelne Zeile aus der Tabelle zur weiteren Verarbeitung entfernt.
Beachten Sie, dass sich die Polling-Logik außerhalb des Transaktionsbereichs befinden muss, da die Snapshot-Isolation für den Zugriff auf die Tabelle t1 verwendet wird. Die Verwendung der Polling-Logik innerhalb des Bereichs einer Transaktion würde eine lang andauernde Transaktion erstellen, was eine schlechte Praxis ist.
-- poll table
WHILE NOT EXISTS (SELECT 1 FROM dbo.t1)
BEGIN
-- if empty, wait and poll again
WAITFOR DELAY '00:00:01'
END
BEGIN TRANSACTION
DECLARE @id int
SELECT TOP 1 @id=id FROM dbo.t1 WITH (SNAPSHOT)
DELETE FROM dbo.t1 WITH (SNAPSHOT) WHERE id=@id
-- insert processing based on @id
COMMIT
Sperren von Tabellenhinweisen
Sperrhinweise (Tabellenhinweise (Transact-SQL)) wie HOLDLOCK und XLOCK können mit datenträgerbasierten Tabellen verwendet werden, damit SQL Server mehr Sperren anwendet, als für die angegebene Isolationsebene erforderlich sind.
Speicheroptimierte Tabellen verwenden keine Sperren. Höhere Isolationsstufen wie REPEATABLE READ und SERIALIZABLE können verwendet werden, um die gewünschten Garantien zu deklarieren.
Sperrhinweise werden nicht unterstützt. Deklarieren Sie stattdessen die erforderlichen Garantien über die Transaktionsisolationsstufen. (NOLOCK wird unterstützt, da SQL Server keine Sperren für speicheroptimierte Tabellen verwendet. Beachten Sie, dass NOLOCK im Gegensatz zu datenträgerbasierten Tabellen kein READ UNCOMMITTED-Verhalten für speicheroptimierte Tabellen impliziert.)
Siehe auch
Grundlegendes zu Transaktionen in Memory-Optimized Tabellen
Richtlinien für die Wiederholungslogik für Transaktionen in Memory-Optimized Tabellen
Transaktionsisolationsstufen