Час очікування закінчився Період часу очікування, який минув до завершення операції, або сервер не відповідає. Заява скасована


295

У мене є багато користувачів на моєму веб-сайті (20000-60000 на день), який є сайтом для завантаження мобільних файлів. У мене віддалений доступ до мого сервера (Windows Server 2008-R2). Раніше
я отримував помилки "Сервер недоступний" , але зараз спостерігається помилка очікування з'єднання.
Я з цим не знайомий - чому це відбувається і як це можна виправити?

Повна помилка нижче:

Помилка серверу в програмі '/' Час очікування закінчився Період часу очікування, який минув до завершення операції, або сервер не відповідає. Заява скасована. Опис: Неопрацьований виняток стався під час виконання поточного веб-запиту. Перегляньте слід стека, щоб отримати докладнішу інформацію про помилку та місце її виникнення в коді.

Деталі винятків: System.Data.SqlClient.SqlException: термін очікування минув. Період часу очікування, який минув до завершення операції, або сервер не відповідає. Заява скасована.

Помилка джерела:

Неопрацьоване виняток було створено під час виконання поточного веб-запиту. Інформацію про походження та місцезнаходження винятку можна ідентифікувати за допомогою сліду стека винятку нижче.

Слід стека:

[SqlException (0x80131904): Термін очікування минув. Період часу очікування, який минув до завершення операції, або сервер не відповідає. Заява була припинена.]
System.Data.SqlClient.SqlConnection.OnError (SqlException виняток, булева breakConnection) +404
System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning () +412
System.Data.SqlClient.TdsParser.Run (RunBehavior runBehavior , SqlCommand cmdHandler, SqlDataReader DATASTREAM, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj) +1363
System.Data.SqlClient.SqlCommand.FinishExecuteReader (SqlDataReader Д.С., RunBehavior runBehavior, String resetOptionsString) +6387741
System.Data.SqlClient.SqlCommand.RunExecuteReaderTds (CommandBehavior cmdBehavior, RunBehavior runBehavior, булева returnStream, булева асинхронний) +6389442
System.Data.SqlClient.SqlCommand.RunExecuteReader (CommandBehavior cmdBehavior, RunBehavior runBehavior, булева returnStream, метод String, результат DbAsyncResult) + 538
System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery (результат DbAsyncResult, метод StringName, булевий sendToPipe) +689
System.Data.SqlClient.SqlCommand.ExecuteNiaTataNaQaek (
NQQeek (NQ ) NQQeek (NQQQ), , Int32 та рядкиAffected) +209
DataLayer.OnlineUsers.Update_SessionEnd_And_Online (Object Session_End, Boolean Online) +440
NiceFileExplorer.Global.Application_Start (відправник об'єкта, EventArgs e) +163

[HttpException (0x80004005): Час очікування минув. Період часу очікування, який минув до завершення операції, або сервер не відповідає. Виписка завершена.]
System.Web.HttpApplicationFactory.EnsureAppStartCalledForIntegratedMode (контекст HttpContext, додаток HttpApplication
) +4052053
System.Web.HttpApplication.RegisterEventSubscriptionsWithIttpіntіntіxtіntіxtіntіntіntіtіntіtіntіtіntіtіntіtіntіntіntіtіntіtіtіntіtіntіtіntіtіtіntіtіntіtіntіtіntіtіntіеntіtіеntеrееs, InitSpecial (HttpApplicationState стану, MethodInfo [] обробники, IntPtr, HttpContext контекст додаток контекст) : +352
System.Web.HttpApplicationFactory.GetSpecialApplicationInstance (IntPtr контекст додаток, HttpContext контекст) +407
System.Web.Hosting.PipelineRuntime.InitializeApplication (IntPtr контекст додаток) +375

[HttpException (0x80004005): Час очікування минув. Період часу очікування, який минув до завершення операції, або сервер не відповідає.
Ствердження було припинено.


РЕДАКТУЙТЕ ПІСЛЯ ВІДПОВІДІВ:
my Application_Startin Global.asaxє як нижче:

protected void Application_Start(object sender, EventArgs e)
{
    Application["OnlineUsers"] = 0;

    OnlineUsers.Update_SessionEnd_And_Online(
        DateTime.Now,
        false);

    AddTask("DoStuff", 10);
}

Збережена процедура, що викликається, така:

ALTER Procedure [dbo].[sp_OnlineUsers_Update_SessionEnd_And_Online]
    @Session_End datetime,
    @Online bit
As
Begin
    Update OnlineUsers
    SET
        [Session_End] = @Session_End,
        [Online] = @Online

End

У мене є два способи залучення користувачів в Інтернеті:

  1. використовуючи Application["OnlineUsers"] = 0;
  2. інший, що використовує базу даних

Отже, для методу №2 я скидаю всі Інтернет-користувачі на Application_Start. У цій таблиці понад 482,751 записів.



1
Краще зробити аналіз першопричини. Існують різні причини, що викликають таку проблему. Найбільш основним є складна структура запиту. Я зіткнувся з тією ж проблемою, коли я отримував зображення, які зберігаються як шістнадцяткові значення в таблиці.
Vijay Kumbhoje

Окрім причин, зазначених вище, я додам ще одну: Час очікування блокування: docs.microsoft.com/en-us/sql/t-sql/statements/… Якщо ця нитка очікує блокування занадто довго, вона буде таймаутом на основі вище документ.
Герберт Ю

Відповіді:


344

Схоже, у вас є запит, який займає більше часу, ніж слід. Із сліду стека та коду ви зможете точно визначити, що це за запит.

Цей тип очікування може мати три причини;

  1. Десь тупик
  2. Статистичні дані бази даних та / або кеш плану запитів є невірними
  3. Запит занадто складний і його потрібно налаштувати

Тупик може бути важко виправити, але легко визначити, чи це так. Підключіться до бази даних за допомогою Sql Server Management Studio. На лівій панелі клацніть правою кнопкою миші на вузлі сервера та виберіть « Монітор активності» . Погляньте на запущені процеси. Зазвичай більшість буде простоювати або працювати. У разі виникнення проблеми ви можете ідентифікувати будь-який заблокований процес за станом процесу. Якщо ви клацніть правою кнопкою миші процес і виберіть деталі, він покаже вам останній запит, виконаний процесом.

Другий випуск призведе до того, що база даних використовуватиме неоптимальний план запитів. Це можна вирішити, очистивши статистику:

exec sp_updatestats

Якщо це не працює, ви також можете спробувати

dbcc freeproccache

Не слід робити цього, коли ваш сервер знаходиться під великим навантаженням, оскільки він тимчасово спричинить велике звернення до перформації, оскільки всі збережені програми та запити перекомпілюються при першому виконанні. Однак, оскільки ви заявляєте, що проблема виникає іноді , і трасування стека вказує на те, що ваша програма запускається, я думаю, ви виконуєте запит, який виконується лише зрідка. Ви можете бути краще, змусивши SQL Server не використовувати повторно попередній план запитів. Дивіться цю відповідь, щоб дізнатися, як це зробити.

Я вже торкнувся третього питання, але ви можете легко визначити, чи потрібен налаштування запиту, виконавши запит вручну, наприклад, використовуючи Sql Server Management Studio. Якщо запит буде зайнятий занадто довго, навіть після скидання статистики вам, ймовірно, знадобиться налаштувати його. Щоб допомогти з цим, ви повинні опублікувати точний запит у новому запитанні.


39
У мене була така сама помилка, але в запиті, який 'просто' зайняв 8 секунд ... і ваша порада про вирішену exec sp_updatestatsмою проблему. Дуже дякую!
1313

2
Вирішення такої проблеми майже ніколи не стосується настройки тайм-аутів або розміру пулу з'єднання. Вам потрібно буде зануритися і з'ясувати першопричину. Якщо вам потрібна допомога у вирішенні цієї першопричини, можете залишити власне запитання.
Marnix van Valen

5
Це, звичайно, не тупик. Це може бути викликано надмірним блокуванням, але тупики вирішуються за секунду, і вони генерують різні помилки. Це може бути надмірне блокування, але не тупик.
Michael J Swart

1
ми впевнені, що це час очікування команди, а не час очікування з'єднання? "System.Data.SqlClient.SqlConnection.OnError" для мене вказує на проблему з підключенням.
Майк Ш

1
@PrashantPimpale Залежить, якщо у вас виникнуть серйозні проблеми у виробництві, коли неправильна статистика призводить до поганих планів виконання, то так, це може бути вирішенням. Якщо заборонити виняткові проблеми (наприклад, несправність обладнання), оновлення статистики не порушить вашу базу даних. Це може спричинити повільніші запити на деякий час. Зрештою, це ваш дзвінок.
Marnix van Valen

155

У вашому коді, де ви запускаєте збережену процедуру, ви повинні мати щось подібне:

SqlCommand c = new SqlCommand(...)
//...

Додайте такий рядок коду:

c.CommandTimeout = 0;

Це зачекатиме стільки часу, скільки потрібно для завершення операції.


143
Також слід пам’ятати, що значення 0 не рекомендується : значення 0 вказує без обмежень, і його слід уникати в CommandTimeout, оскільки спроба виконання команди буде чекати нескінченно. Краще дізнатися, скільки часу займає команда, і при необхідності збільшити значення Timeout.
Отьєль

7
Я погоджуюсь з Otiel і заборонив вашу відповідь: Під час встановлення commandTimeout до 0 ви не даєте веб-серверу можливості відновитись із сервера баз даних, який не відповідає. По-друге, коли ви потрапляєте у режим очікування за замовчуванням, вам слід розглянути причину. У більшості випадків краще виправити запит, ніж збільшувати час очікування.
Maarten Kieft

10
Я б не потрапив у пастку не рекомендувати його. Це було дуже корисно для мене та моїх щоденних запланованих завдань: Надання нескінченного тайм-ауту не зупиняє процес завершення та повернення помилки, якщо щось піде не так. Простіше кажучи, це просто дозволяє вам дозволити завершення запиту, коли це потрібно, не створюючи проблем потім, оскільки ви не виділили достатньо часу для завершення процесу. Ви також можете уникнути блокування програми за допомогою багатопотокової передачі.
WonderWorker

2
Так, для великих передач даних, якщо це не встановлено, немає сенсу. Якщо ви переносите мільйони рядків, то, про що говорять Otiel і BlackHawkDesign, не має сенсу.
bluerubez

За 20 років розвитку, орієнтованого на дані, мені ніколи цього не потрібно було робити. Майже завжди існує досить просте рішення, яке забезпечує кращу продуктивність і не створює можливості для одного процесу, який би перемелювався в базі даних цілий день. Переважна більшість проблем, пов'язаних з виконанням дБ, може бути налаштована на швидкість виконання кількох порядків. Тобто, цей процес, на який ви очікуєте 3 години, може бути налаштований на 3 хвилини або навіть 3 секунди.
b_levitt

25

Ви можете встановити CommandTimeout властивість команди SQL для забезпечення тривалої транзакції SQL.

Вам також може знадобитися переглянути SQL-запит, який викликає тайм-аут.


привіт, "або вам потрібно подивитися на запит SQL, що спричиняє тайм-аут" -> на сервері sql 2008, де я повинен перевірити наявність цього часу?
SilverLight

Можливо, вам доведеться протестувати збережену процедуру, яка викликається з DataLayer.OnlineUsers.Update_SessionEnd_And_Online, як видається, що Trace Track спрямований на неї. Візьміть копію живої бази даних в тест і запустіть Збережену процедуру, проходячи в необхідних параметрах, якщо на це потрібно більше 30 секунд, тому ви отримуєте тайм-аут. Я припускаю, що у вас є доступ до студії управління SQL Server.
Кев Річі

так, у мене є доступ до сервера sql 2008. Я повинен спробувати.
SilverLight

Якщо ви знайдете збережену процедуру, яка спричиняє проблему, ви можете запустити запит, що міститься в збереженій процедурі, через Радник з налаштування бази даних, який підкаже, чи потрібні вам індекси тощо. Посилання тут msdn.microsoft.com/en-us/library /ms174202.aspx
Кев Річі

12

Хоча всі попередні відповіді стосуються цього питання, вони охоплювали не всі випадки.

Microsoft визнала проблему та виправила її у 2011 році для підтримуваних операційних систем, тож якщо ви отримаєте слід сліду:

Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.
at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning()
at System.Data.SqlClient.TdsParserStateObject.ReadSniError(TdsParserStateObject stateObj, UInt32 error)
at System.Data.SqlClient.TdsParserStateObject.ReadSni(DbAsyncResult asyncResult, TdsParserStateObject stateObj)

Вам може знадобитися оновити свої .NET збірки.

Ця проблема виникає через помилку в алгоритмі з'єднання-повтор для дзеркальних баз даних.

Коли використовується алгоритм спроби, постачальник даних чекає завершення першого виклику (SniReadSync). Виклик відправляється на комп’ютер, що працює на сервері, на якому працює SQL Server, і час очікування обчислюється шляхом множення значення тайм-ауту з'єднання на 0,08. Однак постачальник даних неправильно встановлює з'єднання на приречений стан, якщо відповідь повільна і якщо перший дзвінок SniReadSync не завершений до закінчення часу очікування.

Докладніше див. У KB 2605597

https://support.microsoft.com/kb/2605597


9

Можливо, комусь це стане в нагоді. Я зіткнувся з тією ж проблемою, і в моєму випадку причиною було те, що SqlConnection був відкритий і не розміщений у методі, який я викликав у циклі з приблизно 2500 ітераціями. Басейн підключень був вичерпаний. Правильне розпорядження вирішило проблему.


це! саме це. Моя проблема полягала в тому, що я знімав методи з іншого потоку, не чекаючи їх (тому що користувачеві не потрібен результат цього методу, фоновий скрипт). Не розпоряджаючись (використовуючи usingблоки), у мене вийшов цей час очікування. Це ніби вирішило це.
CularBytes

ви отримали помилку тайм-ауту, коли досягнуто максимального пулу з'єднання або минув час очікування. Період часу очікування, який минув до завершення операції або сервер не відповідає. Тому що, якщо ви отримали максимальний пул, досягнутий, має сенс вивчити протікає з'єднання. але я отримую сервер не відповідає на помилку.
Jeeva Subburaj

8

Ви повинні встановити атрибут CommandTimeout. Ви можете встановити атрибут CommandTimeout у дочірньому класі DbContext.

public partial class StudentDatabaseEntities : DbContext
{
    public StudentDatabaseEntities()
        : base("name=StudentDatabaseEntities")
    {
        this.Database.CommandTimeout = 180;
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        throw new UnintentionalCodeFirstException();
    }

    public virtual DbSet<StudentDbTable> StudentDbTables { get; set; }
}

7

Я зіткнувся з тією ж проблемою, над якою працював близько 3 днів. Я помітив, оскільки наша кількість записів не дуже велика, наш старший розробник зберігає в базі 2 зображення та відбитки пальців. Коли я намагаюсь отримати це шістнадцяткові значення, які потребують тривалого часу, я обчислюю середній час для виконання моєї процедури приблизно 38 секунд. Типовий час команди за замовчуванням становить 30 секунд, тому для запуску збереженої процедури потрібно менше середнього часу. Я встановив свій timeout команди, як показано нижче

cmd.CommandTimeout = 50

і він працює нормально, але іноді, якщо ваш запит займе більше 50 секунд, він підкаже ту саму помилку.


4

Нещодавно я зіткнувся з цією помилкою, і після короткого розслідування виявив, що у нас не вистачає місця на диску, на якому розміщена база даних (менше 1 ГБ).

Як тільки я перемістив файли бази даних (.mdf та .ldf) на інший диск на тому ж сервері (з набагато більше місця), та сама сторінка (запуск запиту), що вимкнулась із часу вичерпання протягом трьох секунд.

Ще одне, що потрібно досліджувати, намагаючись вирішити цю помилку, - це розмір файлів журналу бази даних. Ваші файли журналів, можливо, потрібно буде скоротити.


3

У мене є проблема з великим розрахунком в sp_foo, які займають багато часу, тому я виправився
з цим маленьким кодом

public partial class FooEntities : DbContext
{
   public FooEntities()
         : base("name=FooEntities")
    {
        this.Configuration.LazyLoadingEnabled = false;

        // Get the ObjectContext related to this DbContext
        var objectContext = (this as IObjectContextAdapter).ObjectContext;

        // Sets the command timeout for all the commands
        objectContext.CommandTimeout = 380;
    }

3

Час очікування за замовчуванням становить 15 секунд, щоб змінити, що 0 не обмежено, будь-яке інше число - це кількість секунд.

В Кодексі

using (SqlCommand sqlCmd = new SqlCommand(sqlQueryString, sqlConnection))
   {
      sqlCmd.CommandTimeout = 0; // 0 = give it as much time as it needs to complete
      ...
    }

У вашому Web.Config "Timeout Time = 0;" не затримати час або менше 1 години (3600 секунд)

  <add name="ConnectionString" connectionString="Data Source=ServerName;User ID=UserName;Password=Password;Command Timeout=3600;" providerName="System.Data.SqlClient" />

2
Це два різних тайм-аута. Ваша перша пропозиція стосується цього питання. Ваш другий працює лише в тому випадку, якщо постачальник з'єднань його підтримує, чого SqlClient не робить. У будь-якому випадку, тайм-аут 0 ніколи не є хорошою ідеєю у виробництві. 30 секунд - це звичайний дефолт.
Suncat2000

2

@SilverLight .. Очевидно, це проблема з об'єктом Database. Це може бути погано написаний запит або відсутні індекси. Але на даний момент я не пропоную вам збільшувати час очікування, не досліджуючи проблему з вашими об’єктами Бази даних

NovinMedia.Data.DbObject.RunProcedure(String storedProcName, IDataParameter[] parameters, Int32& rowsAffected) +209

Поставте крапку в цьому рядку коду, щоб знайти назву процедури, а потім оптимізуйте процедуру, переглянувши план її виконання.

Я не можу вам допомогти більше, доки ви не розмістите деталі про збережену процедуру.


Збережена процедура не робить будь-яких фантазійних речей. Однак здається, що таблиця OnlineUsers блокується під час виконання процедури. Спробуйте профілер SQL, щоб побачити, що відбувається в Application_Start
Amit Rai Sharma

2

спробуйте

EXEC SP_CONFIGURE 'remote query timeout', 1800
reconfigure
EXEC sp_configure

EXEC SP_CONFIGURE 'show advanced options', 1
reconfigure
EXEC sp_configure

EXEC SP_CONFIGURE 'remote query timeout', 1800
reconfigure
EXEC sp_configure

потім відновіть свій індекс


8
Чи можете ви пояснити своє рішення?
Hp93

0

Час закінчення минув, оскільки запит sql займає більше часу, ніж ви встановили у властивості sqlCommand.CommandTimeout.

Очевидно, ви можете збільшити CommandTimeout, щоб вирішити цю проблему, але перед цим потрібно оптимізувати запит, додавши індекс. Якщо ви запускаєте запит у студії управління сервером Sql, включаючи фактичний план виконання, тоді студія управління сервером Sql запропонує вам отримати відповідний індекс. У більшості випадків ви позбудетеся проблеми з таймаутом, якщо зможете оптимізувати запит.


0

TLDR :

  1. Перезавантаження і серверів додатків, і серверів БД - найшвидший виправлення, коли обсяг даних, мережеві настройки та код не змінилися. Ми завжди робимо це як правило
  2. Може бути індикатором відмови жорсткого диска, який потребує заміни - перевірте системні сповіщення

Я часто стикався з цією помилкою з різних причин і мав різні рішення, зокрема:

  1. рефакторинг мого коду для використання SqlBulkCopy
  2. збільшення значень тайм-ауту, як зазначено в різних відповідях або перевірка основних причин ( можливо, не пов’язані з даними )
  3. Час очікування підключення (за замовчуванням 15 секунд) - скільки часу потрібно чекати встановлення з'єднання з сервером SQL перед припиненням - пов'язане з TCP / PORT - може пройти контрольний список усунення несправностей (дуже зручна стаття MSDN)
  4. Час очікування команди (за замовчуванням 30 років) - Скільки часу потрібно чекати на виконання запиту - Виконання запиту / пов'язаний з мережевим трафіком - також має процес усунення несправностей (ще одна дуже зручна стаття MSDN)
  5. Перезавантаження сервера (серверів) - програми та сервера БД (якщо є окремими) - там, де код і дані не змінилися, середовище повинно змінитися - Перше, що потрібно зробити. Зазвичай викликає патчі (операційна система, .Net Framework або патчі або оновлення SQL Server). Особливо, якщо виняток із тайм-ауту відображається нижче (навіть якщо ми не використовуємо Azure):
    • System.Data.Entity.Core.EntityException: Винято виняток, який, ймовірно, пов'язаний з тимчасовим збоєм. Якщо ви підключаєтесь до бази даних SQL Azure, розгляньте можливість використання SqlAzureExecutionStrategy. ---> System.Data.Entity.Core.EntityCommandExecutionException: Під час виконання визначення команди сталася помилка. Деталі див. У внутрішньому виключенні. ---> System.Data.SqlClient.SqlException: При отриманні результатів від сервера сталася помилка на транспортному рівні. (постачальник: TCP Provider, помилка: 0 - Термін очікування семафору закінчився.) ---> System.ComponentModel.Win32Exception: Термін очікування семафору закінчився

0

Також переконайтеся, що у вас просто немає очікуваної транзакції. :)

Я робив кілька тестів навколо і почав транзакцію в безпеці, але ніколи не закривав її. Я хотів би, щоб помилка була більш чіткою, але так добре!


0

У нас були важкі часи Timeout expired/max pool reached Sqlexception. Як робоче середовище і для запобігання перезапуску сервера або служби ми змінюємо MAX SERVER MEMORYзмінну в SQL Server (або через SQL Management Studio або T-SQL):

DECLARE @maxMem INT = 3000 --Max. memory for SQL Server instance in MB
EXEC sp_configure 'show advanced options', 1
RECONFIGURE

Це тимчасово вирішує проблему, поки це не повториться. У нашому випадку ми підозрюємо, що це стосується витоків підключення на рівні програми.


0

Нещодавно ми оновили до версії NuGet SqlClient( Microsoft.Data.SqlClient), яка містить помилку . Ця помилка була введена протягом життя циклу 1.x та її вже виправлено. Виправлення буде доступне у версії 2.0.0, яка недоступна під час написання цього повідомлення. Доступний попередній перегляд

Ви можете ознайомитися з деталями тут: https://github.com/dotnet/SqlClient/isissue/262

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.