Microsoft SQL Server
Transaktionsisolationsnivåer
Sök…
Syntax
- Ställ in TRANSAKTION ISOLATIONSNIVÅ {LÄS UNCOMMITTED | LÄS ÅTAGANDE | REPEATABLE LÄS | SNAPSHOT | SERIALISERBAR} [; ]
Anmärkningar
MSDN-referens: STÄLL IN TRANSAKTION ISOLATIONSNIVÅ
Läs Uncommitted
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
Detta är den mest tillåtna isoleringsnivån eftersom den inte orsakar några lås alls. Den anger att uttalanden kan läsa alla rader, inklusive rader som har skrivits i transaktioner men ännu inte begått (dvs. de är fortfarande i transaktion). Denna isoleringsnivå kan bli föremål för "smutsiga läsningar".
Läs engagerad
SET TRANSACTION ISOLATION LEVEL READ COMMITTED
Denna isoleringsnivå är den 2: a mest tillåtna. Det förhindrar smutsiga läsningar. Beteendet hos READ COMMITTED
beror på inställningen av READ_COMMITTED_SNAPSHOT
:
Om den är inställd på OFF (standardinställningen) använder transaktionen delade lås för att förhindra andra transaktioner från att ändra rader som används av den aktuella transaktionen, samt för att blockera den aktuella transaktionen från att läsa rader som har ändrats av andra transaktioner.
Om den är inställd på ON
READCOMMITTEDLOCK
tabellenREADCOMMITTEDLOCK
användas för att begära delad låsning istället för radversion för transaktioner som körs i lägetREAD COMMITTED
.
Obs: READ COMMITTED
är standard SQL Server-beteende.
Vad är "smutsiga läsningar"?
Smutsiga läsningar (eller oåtkomna läsningar) är läsningar av rader som modifieras av en öppen transaktion.
Detta beteende kan replikeras genom att använda två separata frågor: en för att öppna en transaktion och skriva vissa data till en tabell utan att begå, den andra för att välja de data som ska skrivas (men ännu inte begått) med denna isoleringsnivå.
Fråga 1 - Förbered en transaktion men slutför inte den:
CREATE TABLE dbo.demo (
col1 INT,
col2 VARCHAR(255)
);
GO
--This row will get committed normally:
BEGIN TRANSACTION;
INSERT INTO dbo.demo(col1, col2)
VALUES (99, 'Normal transaction');
COMMIT TRANSACTION;
--This row will be "stuck" in an open transaction, causing a dirty read
BEGIN TRANSACTION;
INSERT INTO dbo.demo(col1, col2)
VALUES (42, 'Dirty read');
--Do not COMMIT TRANSACTION or ROLLBACK TRANSACTION here
Fråga 2 - Läs raderna inklusive den öppna transaktionen:
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SELECT * FROM dbo.demo;
Returns:
col1 col2 ----------- --------------------------------------- 99 Normal transaction 42 Dirty read
PS: Glöm inte att städa upp demodata:
COMMIT TRANSACTION;
DROP TABLE dbo.demo;
GO
Upprepbar läsning
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
Denna transaktionsisolationsnivå är något mindre tillåten än READ COMMITTED
, genom att delade lås placeras på all data som läses av varje uttalande i transaktionen och hålls tills transaktionen är klar , i motsats till att den släpps efter varje uttalande.
Obs: Använd det här alternativet endast när det är nödvändigt, eftersom det är mer troligt att det orsakar nedbrytning av READ COMMITTED
än READ COMMITTED
.
Snapshot
SET TRANSACTION ISOLATION LEVEL SNAPSHOT
Specificerar att data som läsas av alla påståenden i en transaktion kommer att vara den transaktionsövergripande versionen av de data som fanns vid transaktionens början, dvs att de bara kommer att läsa data som har begåtts innan transaktionen inleddes.
SNAPSHOT
transaktioner begär eller orsakar inga lås på de data som läses, eftersom det bara är att läsa versionen (eller ögonblicksbilden) av data som fanns vid tidpunkten för transaktionen inleddes.
En transaktion som körs i SNAPSHOT
isoleringsnivå läser bara sina egna dataförändringar medan den körs. Exempelvis kan en transaktion uppdatera vissa rader och sedan läsa de uppdaterade raderna, men den ändringen kommer bara att vara synlig för den aktuella transaktionen tills den har begåtts.
Obs: ALLOW_SNAPSHOT_ISOLATION
måste vara inställt på ON innan SNAPSHOT
isoleringsnivån kan användas.
serializable
SET TRANSACTION ISOLATION LEVEL SERIALIZEABLE
Denna isoleringsnivå är den mest restriktiva. Den begär intervall låser intervallet av nyckelvärden som läses av varje uttalande i transaktionen. Detta innebär också att INSERT
uttalanden från andra transaktioner kommer att blockeras om raderna som ska infogas ligger inom det område som låses av den aktuella transaktionen.
Det här alternativet har samma effekt som att ställa in HOLDLOCK
på alla tabeller i alla SELECT
uttalanden i en transaktion.
Obs: Denna transaktionsisolering har den lägsta samtidigheten och bör endast användas vid behov.