Запрос с участием связанного сервера вызывает ошибку распределенной транзакции, когда транзакция не используется или не требуется

У меня есть многопоточный процесс планировщика (.NET), который вызывает хранимую процедуру, которая должна извлекать данные со связанного сервера и, в конечном итоге, вставлять данные в локальную таблицу. Я не использую явно какие-либо транзакции - меня не беспокоит сбой процесса, так как я могу просто перезапустить его. Кроме того, я хочу избежать сложности распределенных транзакций (MSDTC).

Я сталкиваюсь с тем, что большую часть времени в процессе .NET я получаю следующую ошибку:

The operation could not be performed because OLE DB provider "SQLNCLI11" for linked server "XXXX" was unable to begin a distributed transaction.
OLE DB provider "SQLNCLI11" for linked server "XXXX" returned message "No transaction is active.

Когда я выполняю хранимую процедуру из SQL Server Management Studio, ошибка не возникает. Я пытался отследить, чем выполнение SSMS отличается от .NET, и обнаружил несколько случаев, когда процесс .NET НЕ получал ошибку. Но даже при этом я не могу провести различие между тем, когда это терпит неудачу, и когда это не так.

Для чего бы это ни стоило, я добавил некоторую регистрацию в процедуру для записи @@trancount, которая всегда регистрируется как 2. Я могу понять одну неявную транзакцию для покрытия оператора INSERT для сохранения журнала, но я не могу учитывать вторую. Что бы это ни стоило, моя хранимая процедура фактически вызывает вторую процедуру, которая обращается к связанному серверу - не уверен, что это имеет значение. Все это говорит о том, что @@trancount возвращает 2 даже в случае успеха (и независимо от того, вызывается ли он из SSMS или .NET).

Администратор баз данных изменил свойства связанного сервера, чтобы убедиться, что «включить продвижение распределенных транзакций» не соответствует действительности. Что еще я должен попробовать? Спасибо!


person glancep    schedule 27.07.2017    source источник
comment
IIRC, это либо проблема с определением LinkedServer, либо с настройкой MSDTC на локальном или удаленном SQL Server. Я бы порекомендовал передать это на hhtp://dba.stackexchange.com, где есть больше администраторов баз данных, которые могут знать подробности.   -  person RBarryYoung    schedule 27.07.2017
comment
Кроме того, в этом вопросе содержится много полезной информации: stackoverflow.com/questions/7473508/   -  person RBarryYoung    schedule 27.07.2017
comment
А здесь: stackoverflow.com/questions/18657768/   -  person RBarryYoung    schedule 27.07.2017
comment
@RBarryYoung: спасибо за ответы. Я нашел оба этих вопроса - похоже, почти все работает, как исправить MSDTC. Наши администраторы баз данных отключили эту функцию и предпочли бы оставить ее такой. Кроме того, в этом случае мне даже не нужна транзакция, поэтому мне просто было трудно понять, что я делаю, чтобы вызвать транзакцию. Я только что нашел, что было причиной этого, и опубликую это как ответ.   -  person glancep    schedule 27.07.2017


Ответы (1)


Я обнаружил, что вызвало попытку транзакции в первую очередь (что и было моей целью, поскольку мне не нужна транзакция). Процедура получения данных со связанного сервера вставляла эти данные в таблицу #temp с использованием шаблона SELECT ... INTO #temp. Поскольку таблица, из которой он выбирал, находилась на связанном сервере, я полагаю, что там также создавалась временная таблица. Либо так, либо она по-прежнему создавала временную таблицу локально, но, поскольку выбранная таблица находилась на связанном сервере, она пыталась расширить транзакцию (неявную для оператора вставки), чтобы охватить как локальный, так и связанный сервер.

В любом случае, когда я решил создать временную таблицу в отдельном операторе перед оператором INSERT ... SELECT, он работал без ошибок!

Что это не объясняет мне, так это то, почему процедура будет работать (каждый раз через SSMS и редко через .NET). Я собираюсь каким-то образом списать это на различные планы выполнения... и магию вуду SQL Server.

person glancep    schedule 27.07.2017