SQL 2005 Запрос к связанному серверу периодически дает сбой - PullRequest
4 голосов
/ 28 января 2009

У нас есть база данных, работающая на SQL 2005. Одна из процедур сохранения ищет адрес электронной почты пользователя из Active Directory, используя связанный сервер. Вызов на связанный сервер происходит в функции базы данных.

Я могу в первый раз успешно позвонить из моего приложения Asp.Net, но периодически после этого происходит сбой со следующей ошибкой:

{"Запрошенная операция не может быть выполнена, поскольку поставщик OLE DB \" ADsDSOObject \ "для связанного сервера \" ADSI \ "не поддерживает требуемый интерфейс транзакции."}

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

Есть ли какая-то транзакция, которая остается открытой, которая естественным образом умирает, если я не пытаюсь вызвать процедуру снова? Я в недоумении.

Вот простой вызов в хранимой процедуре:

DECLARE @email varchar(50)


SELECT @email = LEFT(mail, 50)
FROM OPENQUERY (
    ADSI,
    'SELECT mail, sAMAccountName FROM ''LDAP://DC=Katz,DC=COM'' WHERE objectCategory = ''Person'' AND objectClass = ''User'''
)
WHERE sAMAccountName = CAST(@LoginName AS varchar(35))

RETURN @email

Ответы [ 5 ]

3 голосов
/ 28 января 2009

Я часто работал с серверами ссылок SQL Server, хотя и редко с LDAP-запросами ... но мне стало любопытно и я прочитал страницу поддержки Microsoft, на которую ссылается предыдущий пост Рика Токио. Внизу написано:

Это типично для сервера каталогов для обеспечения ограничения сервера на количество объектов, которые будут возвращается по заданному запросу. Это к предотвратить атаки типа «отказ в обслуживании» и перегрузка сети. Чтобы правильно запросить сервер каталогов, большие запросы должен быть разбит на множество меньших из них. Один из способов сделать это через Процесс называется пейджингом. Пока пейджинг доступны через OLEDB ADSI провайдер, в данный момент нет возможности доступны для выполнения из SQL распределенный запрос. Это означает, что общее количество объектов, которые могут быть возвращается по запросу сервер предел. В Windows 2000 Active Каталог, ограничение по умолчанию для сервера 1000 предметов.

Я думаю, что причина того, что это не сработало на вас (или нет), в зависимости от того, вызываете ли вы его из приложения или из «быстрого сценария сдвига» (как вы это выразили), может быть связана с контекстом безопасности под которой выполняется операция. В зависимости от того, как было установлено соединение с сервером ссылок, операция может выполняться с различными учетными данными в зависимости от того, как вы инициируете запрос.

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

2 голосов
/ 29 января 2009

Вместо того, чтобы запрашивать Active Directory через связанный сервер, вам может быть лучше кэшировать данные AD в базу данных SQL, а затем запрашивать их. Вы можете использовать Integration Services, создав соединение OLE DB с помощью «OLE DB PRovider для служб каталогов Microsoft» и имея источник DataReader с запросом, подобным следующему:

    SELECT physicalDeliveryOfficeName, department, company, title, displayName, SN, 
    givenName, sAMAccountName, manager, mail, telephoneNumber, mobile  
    FROM 'LDAP://DC=SOMECO,DC=COM' 
    WHERE objectClass='User'  and objectCategory = 'Person' 
    order by mail 

Используя этот метод, вы все равно столкнетесь с пределом в 1000 строк для результатов запроса AD (обратите внимание, что НЕ рекомендуется увеличивать этот предел в AD, он предотвращает перегрузку контроллера домена). Иногда возможно использовать комбинацию запросов для возврата полного набора данных, например, имена A - L и M - Z

В качестве альтернативы вы можете использовать утилиту командной строки CSVDE в Windows Server, чтобы экспортировать информацию о вашем каталоге в файл CSV и затем импортировать ее в базу данных SQL (см. http://computerperformance.co.uk/Logon/Logon_CSVDE_Export.htm для получения дополнительной информации об экспорте данных AD с помощью CSVDE). .

1 голос
/ 10 марта 2009

Я подозреваю, что это может быть план кэшированных запросов из-за вашего заявления о том, что «Когда я пытаюсь вызвать функцию в быстром сдвиговом скрипте SQL, он работает нормально каждый раз (даже при быстрой проверке)»

Не могли бы вы попробовать выполнить хранимую процедуру следующим образом:

EXEC usp_MyProcedure WITH RECOMPILE
1 голос
/ 28 января 2009

пожалуйста, прочитайте страницу поддержки от Microsoft

0 голосов
/ 03 февраля 2016

Этот вопрос появляется в верхней части первой страницы Google при поиске строки ошибки, но не имеет правильного ответа.

Эта ошибка возникает периодически, когда уровень изоляции не указан ни в коде .NET, ни в процедуре хранения.

Эта ошибка также происходит в SQL Server 2008.

Исправление принудительно SET TRANSACTION ISOLATION LEVEL READ (UN)COMMITTED, поскольку более высокий уровень изоляции не поддерживается Active Directory, а SQL Server пытается использовать SERIALIZABLE.

Теперь, поскольку эта ошибка временная. Почему ADO.NET или SQLServer иногда переключают свою изоляцию по умолчанию на SERIALIZABLE, а иногда нет? Что вызывает это переключение?

...