Я пытаюсь найти обходной путь для тупика между инструкциями 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.Да, я знаю о грязном чтении и несогласованности данных, которые могут быть вызваны чтением незафиксированных данных.