Как откатить хранимую процедуру, которая обновляет таблицу - PullRequest
0 голосов
/ 20 февраля 2020

Почему этот оператор ROLLBACK TRANSACTION не работает?

BEGIN TRANSACTION;
DECLARE @foo INT
EXECUTE [database].[dbo].[get_counter] @CounterID='inventory_records', @nextValue=@foo OUTPUT;
ROLLBACK TRANSACTION;

Фон

Я вставляю записи в ERP-систему клиента, построенную на SQL Сервере 19. ERP база данных не имеет автоинкрементных первичных ключей. Вместо этого он использует таблицу с именем counters, где каждая строка имеет поле counterID и поле целого числа value.

Чтобы вставить новую строку в таблицу, такую ​​как inventory_record, сначала нужно вызвать хранимая процедура, подобная этой:

EXECUTE get_counter @counterID='inventory_record'

Эта процедура возвращает параметр OUT с именем @nextValue, который я затем INSERT передаю в таблицу inventory_record в качестве ее uid.

Мне нужно ROLLBACK поведение этой хранимой процедуры, если моя вставка не удалась. Таким образом, счетчик не увеличивается безгранично при неудачных INSERT попытках.

Содержимое get_counter хранимой процедуры

Это очень просто, но также защищено авторским правом. Я суммировал и усек здесь. Счетчики хранятся в виде последовательностей в БД. Поэтому get_counter вызывает sp_sequence_get_range после проверки правильности запрошенного счетчика.

ALTER PROCEDURE get_counter
    @strCounterID varchar(64),
    @iIncrementValue integer = 1, 
    @LastValue BIGINT = NULL OUTPUT
AS

SET NOCOUNT ON
BEGIN

DECLARE 
          @nextSeqVar SQL_VARIANT
        , @lastSeqVar SQL_VARIANT

-- code that confirms valid counter name

BEGIN TRY
    -- code that calls [sp_sequence_get_range]
END TRY
BEGIN CATCH
    THROW
END CATCH

RETURN(@LastValue)
END

Проблема

Счетчик inventory_record всегда приращения. Я не могу откатить его назад.

Если я запускаю SQL в верхней части этого вопроса из SSMS, то SELECT value FROM counters WHERE counterID = 'inventory_record', счетчик увеличивается при каждом выполнении.

I я новичок в обработке транзакций на SQL сервере. Есть идеи, что мне не хватает?

1 Ответ

3 голосов
/ 20 февраля 2020

повторно опубликовать комментарии как ответ для лучшей читабельности.

get_counter использует Sequence Numbers (sp_sequence_get_range). Пожалуйста, обратитесь к документации на Ограничение раздел.

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

Здесь вы можете увидеть простую демонстрацию

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...