2010-01-19 4 views
1

У меня возникла странная проблема с использованием SQL Server 2000 и двух связанных серверов. Уже два года наше решение работает без заминок, но вчера вчера запрос, синхронизирующий данные из одной из баз данных в другую, запустил тайм-аут.SQL Server timeout 2000 от C# .NET

Я подключаюсь к серверу в производственной сети, которая связана с сервером, в котором содержатся заказы, в которых мне нужны данные.

Запрос содержит несколько соединений, но в основном это суммирует то, что делается:

INSERT INTO ProductionDataCache 
    (column1, column2, ...) 
    SELECT tab1.column1, tab1.column2, tab2.column1, tab3.column1 ... 
     FROM linkedserver.database.dbo.Table1 AS tab1 
     JOIN linkedserver.database.dbo.Table2 AS tab2 ON (...) 
     JOIN linkedserver.database.dbo.Tabl32 AS tab3 ON (...) 
     ... 
     WHERE tab1.productionOrderId = @id 
     ORDER BY ... 

Очевидно, что моя первая попытка решить эту проблему было увеличить таймаут от первоначальных 5 минут. Но когда я приехал в 30 минут и все еще получил тайм-аут, я начал подозревать, что что-то еще происходит. Запрос просто не проходит от менее чем за 5 минут до более 30 минут в течение ночи.

Я вывел SQL-запрос (который первоначально был в коде C#) в мои журналы и решил выполнить запрос в Query Analyzer непосредственно на сервере базы данных. К моему большому удивлению, запрос выполнен правильно менее чем за 10 секунд.

Таким образом, я изолировал выполнение SQL в простой тестовой программе и наблюдал за тем же временем запроса как на сервере, изначально выполнявшем это решение, так и при его локальном запуске на сервере базы данных. Также я попытался создать хранимую процедуру и выполнить ее из программы, но это также не работает. Запуск его в Query Analyzer работает нормально менее чем за несколько секунд.

Похоже, что проблема возникает только при выполнении этого запроса из программы C#. Кто-нибудь видел такое поведение раньше и нашел для него решение?

ОБНОВЛЕНИЕ: Я использовал SQL Profiler на сервере. Очевидное различие заключается в том, что при выполнении запроса из .NET-программы он отображается в журнале как «exec sp_executesql N'INSERT INTO ...», но при выполнении из Query Analyzer он встречается как обычный запрос в журнале ,

Далее я попытался подключить SQL Query Analyzer, используя тот же SQL-пользователь, что и программа, и это также вызвало проблему в Query Analyzer. Похоже, проблема возникает только при подключении через TCP/IP с использованием пользователя sql.

+1

Вы уверены, что какие-либо логины, выполняющие этот код, не заблокированы или не изменены доменами? Кроме того, это звучит скорее как проблема безопасности, чем что-либо еще. Как работает программа под какой учетной записью? – JonH

+0

Я попытался выполнить простой запрос SELECT COUNT (*), чтобы убедиться, что программа фактически обменивалась данными с сервером БД и могла получить от него какие-либо результаты. Это отлично работает. –

ответ

0

Есть несколько вещей для расследования; первый - SET опций; они могут сделать огромным отличием от некоторых запросов. Посмотрите на параметры SET в трассировке и повторите их при тестировании в Management Studio (или Query Analyzer). Обратите внимание, что вам нужно будет посмотреть фактический сеанс профиля, чтобы действительно увидеть их (а не только то, что ваших журналов кода).

Следующее, что я хотел бы рассмотреть, это транзакции; какую модель транзакций вы используете в своем C#? Любые? Никто? Какая изоляция? Сериализуемый? Возможно, распределено? Может быть, на столе есть какой-то неясный замок.

Конечно, если проблема блокировки, вы можете что-то увидеть через sp_who/sp_who2 во время выполнения запроса.