Атомарные блоки в собственных процедурах

Область применения: SQL Server База данных SQL Azure Управляемый экземпляр SQL Azure

BEGIN ATOMIC — часть стандарта ANSI SQL. SQL Server поддерживает атомарные блоки на верхнем уровне скомпилированных хранимых процедур, а также для скомпилированных в собственном коде скалярных пользовательских функций. Дополнительные сведения об этих функциях см. в разделе Скалярные определяемые пользователем функции для выполняющейся в памяти OLTP.

  • Каждая скомпилированная в собственном коде хранимая процедура содержит ровно один блок инструкций Transact-SQL. Это блок ATOMIC.

  • Не собственные, интерпретированные хранимые процедуры Transact-SQL и нерегламентированные пакеты не поддерживают атомарные блоки.

Атомарные блоки выполняются (как единое целое) в пределах транзакции. Либо все инструкции в блоке выполняются успешно, либо весь блок будет подвергнут откату до точки сохранения, созданной в начале блока. Кроме того, параметры сеанса зафиксированы для атомарного блока. Выполнение того же блока ATOMIC в сеансах с различными параметрами приведет к тому же поведению независимо от параметров текущего сеанса.

Транзакции и обработка ошибок

Если транзакция уже существует в сеансе (поскольку пакет выполнил инструкцию BEGIN TRANSACTION и транзакция остается активной), то при запуске блока ATOMIC создается точка сохранения в транзакции. Если блок завершается без исключения, точка сохранения, созданная для этого блока, фиксируется, но сама транзакция не будет зафиксирована, пока не будет зафиксирована транзакция на уровне сеанса. Если в блоке возникает исключение, изменения, выполненные в этом блоке, откатываются, но транзакция на уровне сеанса будет продолжена, если только это исключение не делает продолжение транзакции невозможным. Например, конфликт записи приводит к прерыванию транзакции, а ошибка приведения типов — нет.

Если отсутствуют активные транзакции в сеансе, то BEGIN ATOMIC запускает новую транзакцию. Если вне блока не возникло исключение, то транзакция будет зафиксирована в конце блока. Если в блоке кода возникает исключение (то есть исключение не перехватывается и не обрабатывается внутри блока), транзакция будет откатана. Для транзакций, которые ограничиваются одним атомарным блоком (одной хранимой процедурой, скомпилированной в собственный код), не требуется явно указывать операторы BEGIN TRANSACTION и COMMIT или ROLLBACK.

Все хранимые процедуры, скомпилированные в собственном коде, поддерживают конструкции TRY, CATCHи THROW для обработки ошибок. ФункцияRAISERROR не поддерживается.

Следующий пример иллюстрирует работу функции обработки ошибок с блоками ATOMIC и хранимыми процедурами, скомпилированными в собственном коде:

-- 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  

Следующие сообщения об ошибках, относящиеся к таблицам, оптимизированным для памяти, приводят к невозможности продолжения транзакции. Если они встречаются в атомарном блоке, это приведет к тому, что транзакция будет прервана: 10772, 41301, 41302, 41305, 41325, 41332, 41333 и 41839.

Параметры сеанса

Параметры сеанса в атомарных блоках определяются при компиляции хранимой процедуры. Некоторые параметры могут быть заданы с помощью BEGIN ATOMIC , тогда как другие параметры всегда фиксируются в одно и то же значение.

Для BEGIN ATOMIC требуются следующие параметры:

Обязательный параметр Описание
TRANSACTION ISOLATION LEVEL Поддерживаются значения SNAPSHOT, REPEATABLEREADи SERIALIZABLE.
LANGUAGE Определяет форматы даты и времени и системных сообщений. Поддерживаются все языки и псевдонимы в sys.syslanguages (Transact-SQL ).

Следующие параметры являются необязательными.

Необязательная настройка Описание
DATEFORMAT Поддерживаются все форматы дат SQL Server. Если указан DATEFORMAT, он переопределяет формат даты по умолчанию, связанный с LANGUAGE.
DATEFIRST Если указано значение DATEFIRST, оно переопределяет значение по умолчанию для LANGUAGE.
DELAYED_DURABILITY Поддерживаются значения OFF и ON.

Подтверждения транзакций SQL Server могут быть либо полностью устойчивыми (вариант по умолчанию), либо с отложенной устойчивостью. Дополнительные сведения см. в разделе Управление устойчивостью транзакций.

Следующие SET параметры имеют одинаковое системное значение по умолчанию для всех атомарных блоков во всех хранимых процедурах с нативной компиляцией:

Задать параметр Системное значение по умолчанию для Atomic Blocks
ANSI_NULLS Вкл.
ANSI_PADDING Вкл.
ANSI_WARNING Вкл.
ARITHABORT Вкл.
ARITHIGNORE ВЫКЛ.
CONCAT_NULL_YIELDS_NULL Вкл.
IDENTITY_INSERT ВЫКЛ.
NOCOUNT Вкл.
NUMERIC_ROUNDABORT ВЫКЛ.
QUOTED_IDENTIFIER Вкл.
ROWCOUNT 0
TEXTSIZE 0
XACT_ABORT ВЫКЛ.

Неперехваченные исключения приводят к откату атомарного блока, но не приводят к прерыванию транзакции, если только ошибка не переводит транзакцию в состояние, исключающее её продолжение.

См. также

Скомпилированные в собственном коде хранимые процедуры