Отладка жесткого тайм-аута LINQ-to-SQL - PullRequest
5 голосов
/ 10 марта 2010

Я получаю сообщение об ошибке тайм-аута при попытке выполнить запрос LINQ (-to-SQL)

System.Data.SqlClient.SqlException: истекло время ожидания. Время ожидания истекло до завершения операции или сервер не отвечает.

Теперь это , а не , просто случай медленного запроса:

  • Я запускаю эквивалентный SQL в SQL Management Studio, и он быстро завершается (2 секунды)
  • Я устанавливаю свой CommandTimeout на 2 минуты.
  • Когда я выполняю тот же запрос в модульном тесте, он завершается успешно и быстро. То есть: я получаю этот таймаут, только когда запускаю этот запрос вместе с другими запросами. Тайм-аут всегда происходит при одном и том же вызове.

Этот последний пункт заставил меня подумать, что у меня возникла какая-то тупиковая ситуация на стороне базы данных: запрос где-то блокируется блокировкой, и время ожидания истекает, убивая остановленное соединение.

Проблема с этой идеей состоит в том, что я только делаю выборки в DataContext, что вызывает проблемы. (У меня есть вставки, происходящие в другой базе данных / DataContexts.) У меня также нет явных транзакций. Это немного сбивает меня с толку: поведение запроса выглядит точно как тупик, но у меня никогда не было тупика, который не был вызван какой-то проблемой изоляции транзакций раньше - и это не похоже на случай здесь (в любом случае на первый взгляд).

Я ищу совет по устранению этой проблемы. На какие вещи я должен обратить внимание, чтобы определить причину этой проблемы?

EDIT

Некоторые примечания, которые могут быть полезны:

  • Я опрашиваю мнение, которое ссылается на:
    • Другие представления в той же базе данных
    • Синонимы, которые указывают на таблицы в другой базе данных через связанный сервер.
  • В этом представлении используется union для объединения результатов нескольких запросов

ЭПИЛОГ

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

Ответы [ 2 ]

4 голосов
/ 10 марта 2010

снова запустите ваш код из приложения, пока он ждет (в течение 2 минут ??), запустите это в окне запроса:

;with Blockers AS
(SELECT
     r.session_id AS spid
         ,r.cpu_time,r.reads,r.writes,r.logical_reads 
         ,r.blocking_session_id AS BlockingSPID
         ,LEFT(OBJECT_NAME(st.objectid, st.dbid),50) AS ShortObjectName
         ,LEFT(DB_NAME(r.database_id),50) AS DatabaseName
         ,s.program_name
         ,s.login_name
         ,OBJECT_NAME(st.objectid, st.dbid) AS ObjectName
         ,SUBSTRING(st.text, (r.statement_start_offset/2)+1,( (CASE r.statement_end_offset
                                                                   WHEN -1 THEN DATALENGTH(st.text)
                                                                   ELSE r.statement_end_offset
                                                               END - r.statement_start_offset
                                                              )/2
                                                            ) + 1
                   ) AS SQLText
     FROM sys.dm_exec_requests                          r
         JOIN sys.dm_exec_sessions                      s ON r.session_id = s.session_id
         CROSS APPLY sys.dm_exec_sql_text (sql_handle) st
     --WHERE r.session_id > 50
)
SELECT Blockers.* FROM Blockers

он покажет вам все блоки во время запуска.

0 голосов
/ 10 марта 2010

Вы уверены, что пул соединений не используется незавершенными ресурсами?

Попробуйте обернуть SqlDataContext в блок using и посмотреть, не исчезнет ли проблема.

...