Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Van toepassing op:SQL Server
Azure SQL Database
Azure SQL Managed Instance
In dit artikel worden alle aspecten van transacties beschreven die specifiek zijn voor tabellen die zijn geoptimaliseerd voor geheugen en systeemeigen opgeslagen procedures.
De transactieisolatieniveaus in SQL Server zijn verschillend van toepassing op tabellen die zijn geoptimaliseerd voor geheugen versus tabellen op basis van schijven, en de onderliggende mechanismen verschillen. Een goed begrip van de verschillen helpt de programmeur bij het ontwerpen van een systeem met hoge doorvoer. Het doel van transactie-integriteit wordt in alle gevallen gedeeld.
Voor foutvoorwaarden die specifiek zijn voor transacties in tabellen die zijn geoptimaliseerd voor geheugen, gaat u naar de sectie Conflictdetectie en Logica voor opnieuw proberen.
Zie SET TRANSACTION ISOLATION LEVEL (Transact-SQL)voor algemene informatie.
Pessimistisch versus optimistisch
De functionele verschillen worden veroorzaakt door pessimistische versus optimistische benaderingen voor transactieintegriteit. Voor geheugen geoptimaliseerde tabellen wordt gebruikgemaakt van de optimistische benadering:
Pessimistische benadering maakt gebruik van vergrendelingen om potentiële conflicten te blokkeren voordat ze optreden. Vergrendelingen worden genomen wanneer de instructie wordt uitgevoerd en vrijgegeven wanneer de transactie wordt bevestigd.
Optimistische benadering detecteert conflicten wanneer ze optreden en voert validatiecontroles uit tijdens het doorvoeren.
- Fout 1205, een impasse, kan niet optreden voor een tabel die is geoptimaliseerd voor geheugen.
De optimistische benadering is minder overhead en is meestal efficiënter, deels omdat transactieconflicten ongebruikelijk zijn in de meeste toepassingen. Het belangrijkste functionele verschil tussen de pessimistische en optimistische benaderingen is dat als er een conflict optreedt, u in de pessimistische benadering wacht, terwijl in de optimistische benadering een van de transacties mislukt en opnieuw moet worden geprobeerd door de klant. De functionele verschillen zijn groter wanneer het herhaalbare leesisolatieniveau van kracht is en het grootste is voor het SERIALIZABLE-niveau.
Transactieinitiatiemodi
SQL Server heeft de volgende modi voor het initiëren van transacties:
Autocommit : het begin van een eenvoudige query of DML-instructie opent impliciet een transactie en het einde van de instructie voert de transactie impliciet door. Autocommit is de standaardinstelling.
- In de autocommit-modus hoeft u meestal geen tabelhint te coderen over het transactie-isolatieniveau op de geheugen-geoptimaliseerde tabel in de FROM-clausule.
Expliciet - uw Transact-SQL bevat de code BEGIN TRANSACTION, samen met een uiteindelijke COMMIT TRANSACTION. Twee of meer uitspraken kunnen in dezelfde transactie worden gegroepeerd.
- In de expliciete modus moet u de database-optie MEMORY_OPTIMIZED_ELEVATE_TO_SNAPSHOT gebruiken, of een tabelhint definiëren die het isolatieniveau van de transactie aangeeft op de geheugen-geoptimaliseerde tabel in de FROM-clausule.
Impliciet : wanneer SET IMPLICIT_TRANSACTION ON van kracht is. Misschien zou een betere naam zijn IMPLICIT_BEGIN_TRANSACTION, omdat al deze optie impliciet het equivalent van een expliciete BEGIN-TRANSACTIE voor elke UPDATE-instructie uitvoert als 0 = @@trancount. Daarom is het aan uw T-SQL-code om uiteindelijk een expliciete DOORVOERTRANSACTIE uit te geven.
ATOMIC BLOCK : alle instructies in ATOMIC-blokken worden altijd uitgevoerd als onderdeel van één transactie. De acties van het atomische blok als geheel worden doorgevoerd bij succes, of de acties worden allemaal teruggedraaid in geval van een fout. Elke systeemeigen gecompileerde opgeslagen procedure vereist een ATOMIC-blok.
Codevoorbeeld met expliciete modus
In het volgende geïnterpreteerde Transact-SQL script wordt gebruikt:
- Een expliciete transactie.
- Een tabel die is geoptimaliseerd voor geheugen, met de naam dbo. Order_mo.
- De isolatieniveau-context van de READ COMMITTED-transactie.
Daarom is het nodig om een tabelhint te hebben voor de tabel die is geoptimaliseerd voor geheugen. De hint moet zijn voor MOMENTOPNAME of een nog meer isolerend niveau. Voor het codevoorbeeld is de hint WITH (SNAPSHOT). Als deze hint wordt verwijderd, heeft het script een fout 41368, waarvoor een automatische nieuwe poging ongepast zou zijn:
Fout 41368
Toegang tot tabellen die zijn geoptimaliseerd voor geheugen met behulp van het isolatieniveau READ COMMITTED wordt alleen ondersteund voor automatisch toewijzen van transacties. Het wordt niet ondersteund voor expliciete of impliciete transacties. Geef een ondersteund isolatieniveau op voor de tabel die is geoptimaliseerd voor geheugen met behulp van een tabelhint, zoals WITH (SNAPSHOT).
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
GO
BEGIN TRANSACTION; -- Explicit transaction.
-- Order_mo is a memory-optimized table.
SELECT * FROM
dbo.Order_mo as o WITH (SNAPSHOT) -- Table hint.
JOIN dbo.Customer as c on c.CustomerId = o.CustomerId;
COMMIT TRANSACTION;
De noodzaak van de WITH (SNAPSHOT) hint kan worden vermeden door het gebruik van de databaseoptie MEMORY_OPTIMIZED_ELEVATE_TO_SNAPSHOT. Wanneer deze optie is ingesteld op ON, wordt de toegang tot een geheugen-geoptimaliseerde tabel onder een lager isolatieniveau automatisch verhoogd naar momentopname-isolatie.
ALTER DATABASE CURRENT
SET MEMORY_OPTIMIZED_ELEVATE_TO_SNAPSHOT = ON;
Rijversiebeheer van gegevensrijen
Tabellen die zijn geoptimaliseerd voor geheugen maken gebruik van een zeer geavanceerd systeem voor rijversiebeheer dat de optimistische benadering efficiënt maakt, zelfs op het meest strikte isolatieniveau van SERIALIZABLE. Zie Inleiding tot Memory-Optimized Tabellen voor meer details.
Schijftabellen hebben indirect een systeem voor rijversiebeheer wanneer READ_COMMITTED_SNAPSHOT of het SNAPSHOT-isolatieniveau van kracht is. Dit systeem is gebaseerd op tempdb, terwijl voor geheugen geoptimaliseerde gegevensstructuren een ingebouwde rijversiering hebben, voor maximale efficiëntie.
Isolatieniveaus
De volgende tabel bevat de mogelijke niveaus van transactieisolatie, in volgorde van minimale isolatie tot de meeste. Zie Conflictdetectie en Logica voor opnieuw proberen voor meer informatie over conflicten die kunnen optreden en logica voor opnieuw proberen om deze conflicten aan te pakken.
| Isolatieniveau | Description |
|---|---|
| NIET-VERZONDEN LEZEN | Niet beschikbaar: geheugen-geoptimaliseerde tabellen kunnen niet worden geopend onder Read Uncommitted isolatieniveau. Het is nog steeds mogelijk om toegang te krijgen tot geheugen-geoptimaliseerde tabellen onder SNAPSHOT isolatie als de TRANSACTION ISOLATION LEVEL op sessieniveau staat op READ UNCOMMITTED, door gebruik te maken van de tabellenhint WITH (SNAPSHOT) of door de database-instelling MEMORY_OPTIMIZED_ELEVATE_TO_SNAPSHOT op AAN te zetten. |
| VASTGELEGD LEZEN | Alleen ondersteund voor tabellen die zijn geoptimaliseerd voor geheugen wanneer de modus voor automatisch samenvoegen van kracht is. Het is nog steeds mogelijk om toegang te krijgen tot geheugen-geoptimaliseerde tabellen onder SNAPSHOT-isolatie als het TRANSACTIEISOLATIE-NIVEAU op sessieniveau is ingesteld op READ COMMITTED, met behulp van de tabel-hint WITH (SNAPSHOT) of het instellen van de database-instelling MEMORY_OPTIMIZED_ELEVATE_TO_SNAPSHOT op AAN. Als de databaseoptie READ_COMMITTED_SNAPSHOT is ingesteld op AAN, is het niet toegestaan om in dezelfde instructie toegang te krijgen tot zowel een tabel die is geoptimaliseerd voor geheugen als een schijftabel onder READ COMMITTED-isolatie. |
| MOMENTOPNAME | Ondersteund voor tabellen die zijn geoptimaliseerd voor geheugen. Internaal is SNAPSHOT het minst veeleisende transactie-isolatieniveau voor geheugen-geoptimaliseerde tabellen. SNAPSHOT gebruikt minder systeemresources dan HERHAALBAAR LEZEN of SERIALIZEERBAAR. |
| HERHAALBARE LEESBEWERKING | Ondersteund voor tabellen die zijn geoptimaliseerd voor geheugen. De garantie die wordt geboden door REPEATABLE READ-isolatie is dat bij doorvoeren geen gelijktijdige transactie een van de rijen heeft bijgewerkt die door deze transactie worden gelezen. Vanwege het optimistische model kunnen gelijktijdige transacties rijen die door deze transactie zijn gelezen, bijwerken. In plaats daarvan wordt bij het bevestigen van de transactie gevalideerd dat REPEATABLE READ-isolatie niet is geschonden. Als dat zo is, wordt deze transactie teruggedraaid en moet deze opnieuw worden geprobeerd. |
| SERIALISEERBAAR | Ondersteund voor tabellen die zijn geoptimaliseerd voor geheugen. Serializeerbaar omdat de isolatie zo strikt is dat het bijna een beetje lijkt op het uitvoeren van de transacties in reeksen in plaats van gelijktijdig. |
Transactiefasen en levensduur
Wanneer een voor geheugen geoptimaliseerde tabel betrokken is, doorloopt de levensduur van een transactie de fasen zoals weergegeven in de volgende afbeelding:
Beschrijvingen van de fasen volgen.
Reguliere verwerking: fase 1 (van 3)
- Deze fase bestaat uit de uitvoering van alle query's en DML-instructies in de query.
- Tijdens deze fase zien de verklaringen de versie van de geheugen-geoptimaliseerde tabellen vanaf de logische begintijd van de transactie.
Validatie: fase 2 (van 3)
- De validatiefase begint met het toewijzen van de eindtijd, waardoor de transactie als logisch is gemarkeerd. Met deze voltooiing worden alle wijzigingen van de transactie zichtbaar voor andere transacties die afhankelijk zijn van deze transactie. De afhankelijke transacties mogen niet worden gecommitteerd totdat deze transactie succesvol is gecommitteerd. Bovendien mogen transacties die dergelijke afhankelijkheden bevatten, geen resultatensets retourneren aan de client, om ervoor te zorgen dat de client alleen gegevens ziet die zijn doorgevoerd in de database.
- Deze fase bestaat uit de herhaalbare lees- en serialiseerbare validatie. Bij herhaalbare leesvalidatie wordt gecontroleerd of een van de rijen die door de transactie zijn gelezen, is bijgewerkt. Voor serialiseerbare validatie wordt gecontroleerd of een rij is ingevoegd in een gegevensbereik dat door deze transactie is gescand. Volgens de tabel in isolatieniveaus en conflicten kunnen zowel herhaalbare lees- als serialiseerbare validatie plaatsvinden bij het gebruik van momentopname-isolatie, om consistentie van unieke en refererende sleutelbeperkingen te valideren.
Commitverwerking: fase 3 (van 3)
- Tijdens de doorvoerfase worden de wijzigingen in duurzame tabellen naar het logboek geschreven en wordt het logboek naar de schijf geschreven. Vervolgens wordt het besturingselement teruggezet naar de client.
- Nadat de doorvoerverwerking is voltooid, krijgen alle afhankelijke transacties een melding dat ze kunnen doorvoeren.
Zoals altijd moet u proberen om uw transactionele werkeenheden zo minimaal en kort mogelijk te houden als geldig is voor uw gegevensbehoeften.
Conflictdetectie en logica voor opnieuw proberen
Er zijn twee soorten transactiegerelateerde foutvoorwaarden die ertoe leiden dat een transactie mislukt en terugdraait. Wanneer een dergelijke fout zich voordoet, moet de transactie in de meeste gevallen opnieuw worden geprobeerd, vergelijkbaar met wanneer er een impasse optreedt.
- Conflicten tussen gelijktijdige transacties. Dit zijn updateconflicten en validatiefouten en kunnen worden veroorzaakt door schendingen van transactieisolatieniveau of schendingen van beperkingen.
- Afhankelijkheidsstoringen. Deze problemen ontstaan door transacties waarvan u afhankelijk bent maar die niet worden uitgevoerd, of door een te groot aantal afhankelijkheden.
Hier volgen de foutvoorwaarden die ertoe kunnen leiden dat transacties mislukken wanneer ze toegang hebben tot tabellen die zijn geoptimaliseerd voor geheugen.
| Foutcode | Description | Oorzaak |
|---|---|---|
| 41302 | Er is geprobeerd een rij bij te werken die is bijgewerkt in een andere transactie sinds het begin van de huidige transactie. | Deze foutvoorwaarde treedt op als twee gelijktijdige transacties proberen dezelfde rij tegelijkertijd bij te werken of te verwijderen. Een van de twee transacties ontvangt dit foutbericht en moet opnieuw worden geprobeerd. |
| 41305 | Herhaalbare leesvalidatiemislukking. Een rij die is gelezen uit een geheugen-geoptimaliseerde tabel, is bijgewerkt door een andere transactie die is doorgevoerd vóór de doorvoering van deze transactie. | Deze fout kan optreden bij het gebruik van HERHAALBARE LEES- of SERIALIZABLE-isolatie, en ook als de acties van een concurrerende transactie een schending van een foreign key-beperking veroorzaken. Dergelijke gelijktijdige schending van beperkingen voor refererende sleutels is zeldzaam en geeft meestal een probleem aan met de toepassingslogica of met gegevensinvoer. De fout kan echter ook optreden als er geen index is voor de kolommen die zijn betrokken bij de FOREIGN-KEY-beperking. Daarom is het advies om altijd een index te creëren op foreign key kolommen in een geheugen-geoptimaliseerde tabel. Zie dit blogbericht, van het SQL Server-klantadviesteam, voor meer gedetailleerde overwegingen over validatiefalingen door foreign key-schendingen. |
| 41325 | Serialiseerbare validatiefout. Er is een nieuwe rij ingevoegd in een reeks die eerder door de huidige transactie is gescand. We noemen dit een fantoomrij. | Deze fout kan optreden bij het gebruik van SERIALIZABLE-isolatie en ook als de acties van een gelijktijdige transactie een schending veroorzaken van een PRIMAIRE SLEUTEL, UNIEK of REFERERENDE SLEUTELbeperking. Dergelijke gelijktijdige beperkingsschending is zeldzaam en geeft meestal een probleem aan met de toepassingslogica of gegevensinvoer. Deze fout kan echter ook optreden als er sprake is van een VREEMDE SLEUTEL-constraint zonder index op de betrokken kolommen. |
| 41301 | Afhankelijkheidsfout: er is een afhankelijkheid genomen op een andere transactie die later niet kon worden doorgevoerd. | Deze transactie (Tx1) was afhankelijk van een andere transactie (Tx2) terwijl die transactie (Tx2) zich in de validatie- of commitverwerkingsfase bevond door gegevens te lezen die door Tx2 zijn geschreven. Tx2 kon zich vervolgens niet doorvoeren. De meest voorkomende oorzaken voor het niet doorvoeren van Tx2 zijn herhaalbare leesbewerkingen (41305) en serialiseerbare (41325) validatiefouten; een minder voorkomende oorzaak is een IO-fout in logboeken. |
| 41823 en 41840 | Het quotum voor gebruikersgegevens in tabellen en tabelvariabelen die zijn geoptimaliseerd voor geheugen, is bereikt. | Fout 41823 is van toepassing op SQL Server Express/Web/Standard Edition, evenals individuele databases in Azure SQL Database. Fout 41840 is van toepassing op elastische pools in Azure SQL Database. In de meeste gevallen geven deze fouten aan dat de maximale grootte van gebruikersgegevens is bereikt en de manier om de fout op te lossen is het verwijderen van gegevens uit tabellen die zijn geoptimaliseerd voor geheugen. Er zijn echter zeldzame gevallen waarin deze fout tijdelijk is. We raden u daarom aan het opnieuw te proberen wanneer deze fouten voor het eerst optreden. Net als de andere fouten in deze lijst, veroorzaken fouten 41823 en 41840 dat de actieve transactie wordt afgebroken. |
| 41839 | Transactie heeft het maximum aantal commit-afhankelijkheden overschreden. |
Van toepassing op: SQL Server 2016 (13.x). Latere versies van SQL Server en Azure SQL Database hebben geen limiet voor het aantal doorvoerafhankelijkheden. Er is een limiet voor het aantal transacties waarvan een bepaalde transactie (Tx1) afhankelijk kan zijn. Deze transacties zijn de uitgaande afhankelijkheden. Daarnaast is er een limiet voor het aantal transacties dat afhankelijk kan zijn van een bepaalde transactie (Tx1). Deze transacties zijn de binnenkomende afhankelijkheden. De limiet voor beide is 8. Het meest voorkomende geval voor deze fout is dat er een groot aantal leestransacties is die toegang hebben tot gegevens die zijn geschreven door één schrijftransactie. De kans dat deze voorwaarde wordt bereikt, neemt toe als de leestransacties allemaal grote scans van dezelfde gegevens uitvoeren en als validatie of doorvoerverwerking van de schrijftransactie lang duurt, bijvoorbeeld als de schrijftransactie grote scans uitvoert onder serialize isolatie (verhoogt de lengte van de validatiefase) of het transactielogboek wordt geplaatst op een traag IO-apparaat voor logboeken (verhoogt de lengte van doorvoerverwerking). Als de leestransacties grote scans uitvoeren en er naar verwachting slechts enkele rijen worden geopend, ontbreekt er mogelijk een index. Als de schrijftransactie gebruikmaakt van serialiseerbare isolatie en grote scans uitvoert, maar naar verwachting slechts enkele rijen opent, is dit ook een indicatie van een ontbrekende index. De limiet voor het aantal doorvoerafhankelijkheden kan worden opgeheven met behulp van traceringsvlag 9926. Gebruik deze traceervlag alleen als u deze foutconditie nog steeds treft nadat u hebt bevestigd dat er geen indexen ontbreken, aangezien misstanden in de bovengenoemde gevallen kunnen worden verhuld. Een andere waarschuwing is dat complexe afhankelijkheidsgrafieken, waarbij elke transactie een groot aantal binnenkomende en uitgaande afhankelijkheden heeft en afzonderlijke transacties veel lagen afhankelijkheden hebben, kan dit tot inefficiëntie in het systeem leiden. |
Logica voor opnieuw proberen
Wanneer een transactie mislukt vanwege een van de bovenstaande voorwaarden, moet de transactie opnieuw worden geprobeerd.
Logica voor opnieuw proberen kan worden geïmplementeerd aan de client- of serverzijde. De algemene aanbeveling is het implementeren van logica voor opnieuw proberen aan de clientzijde, omdat het efficiënter is en u kunt omgaan met resultatensets die door de transactie worden geretourneerd voordat de fout optreedt.
Voorbeeld van T-SQL-code opnieuw proberen
Logica voor opnieuw proberen aan de serverzijde met behulp van T-SQL mag alleen worden gebruikt voor transacties die geen resultatensets retourneren aan de client. Anders kunnen nieuwe pogingen leiden tot extra resultatensets dan de verwachte resultatensets die naar de client worden geretourneerd.
Het volgende geïnterpreteerde T-SQL-script illustreert hoe logica voor opnieuw proberen eruit kan zien voor de fouten die zijn gekoppeld aan transactieconflicten met behulp van tabellen die zijn geoptimaliseerd voor geheugen.
-- Retry logic, in Transact-SQL.
DROP PROCEDURE If Exists usp_update_salesorder_dates;
GO
CREATE PROCEDURE usp_update_salesorder_dates
AS
BEGIN
DECLARE @retry INT = 10;
WHILE (@retry > 0)
BEGIN
BEGIN TRY
BEGIN TRANSACTION;
UPDATE dbo.SalesOrder_mo WITH (SNAPSHOT)
set OrderDate = GetUtcDate()
where CustomerId = 42;
UPDATE dbo.SalesOrder_mo WITH (SNAPSHOT)
set OrderDate = GetUtcDate()
where CustomerId = 43;
COMMIT TRANSACTION;
SET @retry = 0; -- //Stops the loop.
END TRY
BEGIN CATCH
SET @retry -= 1;
IF (@retry > 0 AND
ERROR_NUMBER() in (41302, 41305, 41325, 41301, 41823, 41840, 41839, 1205)
)
BEGIN
IF XACT_STATE() = -1
ROLLBACK TRANSACTION;
WAITFOR DELAY '00:00:00.001';
END
ELSE
BEGIN
PRINT 'Suffered an error for which Retry is inappropriate.';
THROW;
END
END CATCH
END -- //While loop
END;
GO
-- EXECUTE usp_update_salesorder_dates;
Transactie tussen containers
Een transactie wordt een transactie tussen containers genoemd als deze het volgende doet:
- Opent een tabel die is geoptimaliseerd voor geheugen vanuit geïnterpreteerde Transact-SQL; of
- Voert een systeemeigen proc uit wanneer een transactie al is geopend (XACT_STATE() = 1).
De term 'cross-container' is afgeleid van het feit dat de transactie wordt uitgevoerd in de twee containers voor transactiebeheer, één voor schijftabellen en één voor tabellen die zijn geoptimaliseerd voor geheugen.
Binnen een enkele transactie tussen containers kunnen verschillende isolatieniveaus worden gebruikt voor toegang tot schijf-gebaseerde en geheugen-geoptimaliseerde tabellen. Dit verschil wordt uitgedrukt via expliciete tabelhints zoals WITH (SERIALIZABLE) of via de databaseoptie MEMORY_OPTIMIZED_ELEVATE_TO_SNAPSHOT, waarmee impliciet het isolatieniveau voor de geheugen-geoptimaliseerde tabel wordt verhoogd naar momentopname wanneer het TRANSACTION ISOLATION LEVEL is geconfigureerd als READ COMMITTED of READ UNCOMMITTED.
In het volgende Transact-SQL codevoorbeeld:
- De schijftabel, Table_D1, wordt geopend met behulp van het isolatieniveau READ COMMITTED.
- De tabel die is geoptimaliseerd voor geheugen Table_MO7 wordt geopend met behulp van het SERIALIZABLE-isolatieniveau. Table_MO6 heeft geen specifiek isolatieniveau, omdat invoegingen altijd consistent zijn en in wezen worden uitgevoerd onder serialiseerbare isolatie.
-- Different isolation levels for
-- disk-based tables versus memory-optimized tables,
-- within one explicit transaction.
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
go
BEGIN TRANSACTION;
-- Table_D1 is a traditional disk-based table, accessed using READ COMMITTED isolation.
SELECT * FROM Table_D1;
-- Table_MO6 and Table_MO7 are memory-optimized tables.
-- Table_MO7 is accessed using SERIALIZABLE isolation,
-- while Table_MO6 does not have a specific isolation level.
INSERT Table_MO6
SELECT * FROM Table_MO7 WITH (SERIALIZABLE);
COMMIT TRANSACTION;
go
Beperkingen
Transacties tussen databases worden niet ondersteund voor tabellen die zijn geoptimaliseerd voor geheugen. Als een transactie toegang heeft tot een tabel die is geoptimaliseerd voor geheugen, heeft de transactie geen toegang tot een andere database, met uitzondering van:
- tempdb-database.
- Alleen-lezen uit de hoofddatabase.
Gedistribueerde transacties worden niet ondersteund: wanneer BEGIN DISTRIBUTED TRANSACTION wordt gebruikt, heeft de transactie geen toegang tot een tabel die is geoptimaliseerd voor geheugen.
Systeemeigen gecompileerde opgeslagen procedures
In een systeemeigen proc moet het ATOMIC-blok het niveau van transactieisolatie voor het hele blok declareren, zoals:
... BEGIN ATOMIC WITH (TRANSACTION ISOLATION LEVEL = SNAPSHOT, ...) ...
Er zijn geen expliciete instructies voor transactiebeheer toegestaan binnen de hoofdtekst van een systeemeigen proc. BEGIN TRANSACTION, ROLLBACK TRANSACTION, enzovoort, zijn allemaal niet toegestaan.
Zie Atomische blokken voor meer informatie over transactiebeheer met ATOMIC-blokken