Atomiska block i inbyggda procedurer

gäller för:SQL ServerAzure SQL DatabaseAzure SQL Managed Instance

BEGIN ATOMIC är en del av ANSI SQL-standarden. SQL Server stöder atomiska block på den översta nivån av internt kompilerade lagrade procedurer, samt för internt kompilerade, skalära användardefinierade funktioner. Mer information om dessa funktioner finns i Scalar User-Defined Functions for In-Memory OLTP.

  • Varje inbyggt kompilerad lagrad procedur innehåller exakt ett block med Transact-SQL-instruktioner. Det här är ett ATOMIC-block.

  • Externa, tolkade lagrade procedurer i Transact-SQL och ad hoc-batchar stöder inte atomiska block.

Atomiska block körs (atomiskt) i transaktionen. Antingen lyckas alla instruktioner i blocket eller så återställs hela blocket till den savepoint som skapades i början av blocket. Dessutom är sessionsinställningarna fasta för atomblocket. Att köra samma atomiska block i sessioner med olika inställningar resulterar i samma beteende, oberoende av inställningarna för den aktuella sessionen.

Transaktioner och felhantering

Om en transaktion redan finns på en session (eftersom en batch körde ett BEGIN TRANSACTION statement och transaktionen förblir aktiv), kommer start av ett atomiskt block att skapa en sparpunkt i transaktionen. Om blocket avslutas utan undantag, så kommer den sparpunkt som skapades för blocket att bekräftas, men transaktionen kommer inte att bekräftas förrän transaktionen på sessionsnivå har bekräftats. Om blocket genererar ett undantag, återställs effekterna av blocket, men transaktionen på sessionsnivå fortsätter, såvida inte undantaget är fördärvande för transaktionen. Till exempel kan en skrivkonflikt göra en transaktion misslyckad, men inte ett typbestämningsfel.

Om det inte finns någon aktiv transaktion i en session startar BEGIN ATOMIC en ny transaktion. Om inget undantag utlöses utom blockets omfattning, kommer transaktionen att bekräftas när blocket avslutas. Om blocket genererar ett undantag (dvs. undantaget fångas inte och hanteras i blocket) återställs transaktionen. För transaktioner som sträcker sig över ett enda atomiskt block (en enda inbyggt kompilerad lagrad procedur) behöver du inte skriva explicita BEGIN TRANSACTION- och COMMIT- eller ROLLBACK-instruktioner.

Internt kompilerade lagrade procedurer stöder try-, CATCH- och THROW-konstruktionerna för felhantering. RAISERROR stöds inte.

Följande exempel illustrerar beteendet för felhantering med atomiska block och inbyggda kompilerade lagrade procedurer:

-- sample table  
CREATE TABLE dbo.t1 (  
  c1 int not null primary key nonclustered  
)  
WITH (MEMORY_OPTIMIZED=ON)  
GO  
  
-- sample proc that inserts 2 rows  
CREATE PROCEDURE dbo.usp_t1 @v1 bigint not null, @v2 bigint not null  
WITH NATIVE_COMPILATION, SCHEMABINDING, EXECUTE AS OWNER  
AS  
BEGIN ATOMIC  
WITH (TRANSACTION ISOLATION LEVEL = SNAPSHOT, LANGUAGE = N'us_english', DELAYED_DURABILITY = ON)  
  
  INSERT dbo.t1 VALUES (@v1)  
  INSERT dbo.t1 VALUES (@v2)  
  
END  
GO  
  
-- insert two rows  
EXEC dbo.usp_t1 1, 2  
GO  
  
-- verify we have no active transaction  
SELECT @@TRANCOUNT  
GO  
  
-- verify the rows 1 and 2 were committed  
SELECT c1 FROM dbo.t1  
GO  
  
-- execute proc with arithmetic overflow  
EXEC dbo.usp_t1 3, 4444444444444  
GO  
-- expected error message:  
-- Msg 8115, Level 16, State 0, Procedure usp_t1  
-- Arithmetic overflow error converting bigint to data type int.  
  
-- verify we have no active transaction  
SELECT @@TRANCOUNT  
GO  
  
-- verify rows 3 was not committed; usp_t1 has been rolled back  
SELECT c1 FROM dbo.t1  
GO  
  
-- start a new transaction  
BEGIN TRANSACTION  
  -- insert rows 3 and 4  
  EXEC dbo.usp_t1 3, 4  
  
  -- verify there is still an active transaction  
  SELECT @@TRANCOUNT  
  
  -- verify the rows 3 and 4 were inserted  
  SELECT c1 FROM dbo.t1 WITH (SNAPSHOT)   
  ORDER BY c1  
  
  -- catch the arithmetic overflow error  
  BEGIN TRY  
    EXEC dbo.usp_t1 5, 4444444444444  
  END TRY  
  BEGIN CATCH  
    PRINT N'Error occurred: ' + error_message()  
  END CATCH  
  
  -- verify there is still an active transaction  
  SELECT @@TRANCOUNT  
  
  -- verify rows 3 and 4 are still in the table, and row 5 has not been inserted  
  SELECT c1 FROM dbo.t1 WITH (SNAPSHOT)   
  ORDER BY c1  
  
COMMIT  
GO  
  
-- verify we have no active transaction  
SELECT @@TRANCOUNT  
GO  
  
-- verify rows 3 and 4 has been committed  
SELECT c1 FROM dbo.t1  
ORDER BY c1  
GO  

Följande felmeddelanden som är specifika för minnesoptimerade tabeller gör att transaktioner misslyckas. Om de inträffar inom omfånget för ett atomiskt block kommer transaktionen att avbrytas: 10772, 41301, 41302, 41305, 41325, 41332, 41333 och 41839.

Sessionsinställningar

Sessionsinställningarna i atomiska block korrigeras när den lagrade proceduren kompileras. Vissa inställningar kan anges med BEGIN ATOMIC medan andra inställningar alltid är fasta till samma värde.

Följande alternativ krävs med BEGIN ATOMIC:

Obligatorisk inställning Description
TRANSAKTIONSISOLERINGSNIVÅ Värden som stöds är SNAPSHOT, REPEATABLEREAD och SERIALIZABLE.
SPRÅK Avgör datum- och tidsformat och systemmeddelanden. Alla språk och alias i sys.syslanguages (Transact-SQL) stöds.

Följande inställningar är valfria:

Valfri inställning Description
DATUMFORMAT Alla SQL Server-datumformat stöds. När det anges åsidosätter DATEFORMAT det standarddatumformat som är associerat med LANGUAGE.
DATEFIRST När det anges åsidosätter DATEFIRST standardvärdet som är associerat med LANGUAGE.
Fördröjd hållbarhet Värden som stöds är AV och .

SQL Server-transaktionsavslut kan antingen vara fullt hållbara, standardvärdet, eller fördröjt hållbara. Mer information finns i Hantera transaktionshållbarhet.

Följande SET-alternativ har samma systemstandardvärde för alla atomiska block i alla internt kompilerade lagrade procedurer:

Ange alternativ Systemstandard för atomiska block
ANSI_NULLS ON
ANSI_PADDING ON
ANSI_WARNING ON
ARITHABORT ON
ARITHIGNORE AV
CONCAT_NULL_YIELDS_NULL ON
IDENTITY_INSERT AV
NOCOUNT ON
NUMERISK_AVRUND_AVBRYT AV
QUOTED_IDENTIFIER ON
ROWCOUNT 0
TEXTSIZE 0
XACT_ABORT AV

Ohanterade undantag gör att atomblocket återgår, men inte gör att transaktionen avbryts om inte felet är transaktionsdömande.

Se även

Internt kompilerade lagrade procedurer