Выбрать с прочтенным незафиксированным в блоке Catch - PullRequest
0 голосов
/ 30 ноября 2018

Я пытаюсь найти обходной путь для тупика между инструкциями UPDATE и SELECT, который трудно воспроизвести, но происходит на рабочем сервере.По умолчанию оператор SELECT уничтожен, что является предпочтительным.Я бы хотел справиться с этим следующим образом:

  • Запуск SELECT как обычно
  • В случае неудачи запустите SELECT WITH (NOLOCK)

Для имитациитупик я использую этот пример .Я изменил пункт 4. до:

BEGIN
    BEGIN TRY
        SELECT 'TRYING TO SELECT 1'
        select value, * from B where value = 1 or id = 1
        SELECT 'SELECT 1 SUCCESFUL'
    END TRY
    BEGIN CATCH
        SELECT 'TRYING TO SELECT 2'
        select value, * from B with (NOLOCK) where value = 1 or id = 1
        SELECT 'SELECT 2 SUCCESFUL'
    END CATCH
END

Результат, который я получаю:

  • Пытаться выбрать 1
  • Результат SELECT 1 (почему?)
  • Пытаться выбрать 2
  • Результат SELECT 2
  • SELECT 2 SUCCESFUL
  • Ошибка: в конце пакета обнаружена незафиксированная транзакция.Транзакция откатывается.

Я не совсем понимаю, почему вижу результат SELECT 1 ... Тем не менее, если я оберну запрос с BEGIN TRANSACTION / ROLLBACK, как это:

BEGIN
        BEGIN TRANSACTION
        BEGIN TRY
            SELECT 'TRYING TO SELECT 1'
            select value, * from B where value = 1 or id = 1
            COMMIT TRANSACTION;
            SELECT 'SELECT 1 SUCCESFUL'
        END TRY
        BEGIN CATCH
            IF @@trancount > 0 ROLLBACK TRANSACTION
            SELECT 'TRYING TO SELECT 2'
            select value, * from B with (NOLOCK) where value = 1 or id = 1
            SELECT 'SELECT 2 SUCCESFUL'
        END CATCH
END

Что откатывает ожидающую транзакцию UPDATE, чего я не хочу.

Ожидаемый результат - выполнение только первого запроса, если не возникла тупиковая ситуация, и только второго запроса, если это произойдет.

PS.Да, я знаю о грязном чтении и несогласованности данных, которые могут быть вызваны чтением незафиксированных данных.

...