Тайм-аут истек. Время ожидания истекло до завершения операции или сервер не отвечает. Заявление было прекращено

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

Полная ошибка ниже:

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

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

Ошибка источника:

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

Трассировки стека:

[SqlException (0x80131904): истекло время ожидания. Время ожидания истекло до завершения операции или сервер не отвечает. Заявление было прекращено.]
System.Data.SqlClient.SqlConnection.OnError (исключение SqlException, логическое прерывание соединения) +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 ds, 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, String methodName, логическое значение sendToPipe) +689
System.Data.SqlClient.SqlCommand.ExecuteNonQuery () +327
NovinMedia.Data.DbObject.RunProcedure (String selectedProcName, IDataParameter[] параметры, Int32 и rowActed) +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.RegisterEventSubscriptionWithIIS(IntPtr appContext, контекст HttpContext, обработчики MethodInfo[]) +191
System.Web.HttpApplication.InitSpecial (состояние HttpApplicationState, обработчики MethodInfo[], IntPtr appContext, контекст HttpContext) +352
System.Web.HttpApplicationFactory.GetSpecialApplicationInstance (IntPtr appContext, HttpContext context) +407
System.Web.Hosting.PipelineRuntime.InitializeApplication (IntPtr appContext) +375

[HttpException (0x80004005): истекло время ожидания. Время ожидания истекло до завершения операции или сервер не отвечает. Заявление было прекращено.]
System.Web.HttpRuntime.FirstRequestInit (контекст HttpContext) +11686928 System.Web.HttpRuntime.EnsureFirstRequestInit(контекст HttpContext) +141 System.Web.HttpRuntime.ProcessRequestNotificationPrivert, HWWTWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW/W4/ru


РЕДАКТИРОВАТЬ ПОСЛЕ ОТВЕТОВ:
мой Application_Start в 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 я сбрасываю все OnlineUsers в Application_Start, В этой таблице более 482 751 записей.

26 ответов

Решение

Похоже, у вас есть запрос, который занимает больше времени, чем нужно. По трассировке стека и коду вы сможете точно определить, что это за запрос.

Этот тип таймаута может иметь три причины;

  1. Где-то тупик
  2. Статистика базы данных и / или кеш плана запросов неверны
  3. Запрос слишком сложный и должен быть настроен

Тупик может быть трудно исправить, но легко определить, так ли это. Подключитесь к своей базе данных с помощью Sql Server Management Studio. На левой панели щелкните правой кнопкой мыши узел сервера и выберите " Монитор активности". Посмотрите на запущенные процессы. Обычно большинство будет бездействующим или работающим. Когда возникает проблема, вы можете идентифицировать любой заблокированный процесс по состоянию процесса. Если вы щелкнете правой кнопкой мыши по процессу и выберете детали, он покажет вам последний запрос, выполненный процессом.

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

exec sp_updatestats

Если это не сработает, вы также можете попробовать

dbcc freeproccache

Вы не должны делать это, когда ваш сервер находится под большой нагрузкой, потому что он временно подвергнется значительному снижению производительности, поскольку все хранимые процессы и запросы перекомпилируются при первом выполнении. Однако, поскольку вы заявляете, что проблема возникает иногда, и трассировка стека указывает, что ваше приложение запускается, я думаю, что вы выполняете запрос, который запускается только изредка. Возможно, вам будет лучше, если вы заставите SQL Server не использовать предыдущий план запроса. Смотрите этот ответ для деталей о том, как это сделать.

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

В вашем коде, где вы запускаете хранимую процедуру, у вас должно быть что-то вроде этого:

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

Добавьте такую ​​строку кода:

c.CommandTimeout = 0;

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

Вы могли бы установить CommandTimeout свойство команды SQL, позволяющее выполнять длительные транзакции SQL.

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

У меня была такая же проблема, и я решил ее путем добавления значения "Время подключения" в файл web.config. найдите строки подключения и добавьте время ожидания подключения =3600"

вот образец

  <connectionStrings>
    <add name="MyConn" providerName="System.Data.SqlClient" connectionString="Data Source=MySQLServer;Initial Catalog=MyDB;User ID=sa;Password=123;Connection Timeout=3600" />
  </connectionStrings>

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

Хотя все предыдущие ответы касались этой проблемы, они не охватывали все случаи.

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

Вы должны установить атрибут 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; }
}

Я столкнулся с той же проблемой, работал над этим около 3 дней. Я заметил, что наше количество записей невелико, наш старший разработчик хранит в базе данных 2 изображения и отпечаток пальца. Когда я пытаюсь получить эти шестнадцатеричные значения, которые занимают много времени, я вычисляю среднее время выполнения моей процедуры, примерно 38 секунд. Время ожидания команды по умолчанию составляет 30 секунд, поэтому оно меньше среднего времени, необходимого для запуска моей хранимой процедуры. Я установил свой тайм-аут команды, как показано ниже

cmd.CommandTimeout = 50

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

Если вы используете ASP.NET Core с Startup.cs соглашения, вы можете получить доступ и установить параметр тайм-аута команды запроса следующим образом:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContextPool<MyDbContext>(_ =>
    {
        _.UseSqlServer(Configuration.GetConnectionString("MyConnectionString"), options => 
        {
            options.CommandTimeout(180); // 3 minutes
        });
    });
}

Время ожидания по умолчанию составляет 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 "Тайм-аут команды =0;" не превышать время ожидания или менее 1 часа (3600 секунд)

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

Я недавно столкнулся с этой ошибкой и после небольшого исследования обнаружил, что причина в том, что у нас заканчивается свободное место на диске, на котором находится база данных (менее 1 ГБ).

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

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

У меня проблема с большими вычислениями в 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;
    }

TL; DR:

  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, ошибка: 0 - период тайм-аута семафора истек.) ---> System.ComponentModel.Win32Exception: истек срок тайм-аута семафора

Однажды у меня была эта проблема, и в моем случае это была незавершенная транзакция в SQL. После того, как я совершил коммит, проблема исчезла.

В моем случае я использовал EntityFrameworkCore.
Поскольку ввод, который я хотел обработать, превысил лимит запроса, эта ошибка пришла ко мне.
Решение для моего случая состояло в том, чтобы разделить обработку данных на куски , и с помощью этого подхода я смог уложиться в ограничения.
Да, это требует времени, но по крайней мере обрабатывает все входные записи.

Пытаться

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

затем перестройте свой индекс

@SilverLight.. Это явно проблема с объектом базы данных. Это может быть плохо написанный запрос или отсутствующие индексы. Но на данный момент я не буду предлагать вам увеличивать время ожидания, не исследуя проблему с вашими объектами базы данных.

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

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

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

У меня была эта проблема, и она исчезла, когда я перешел с ADO.Net на Dapper для своих запросов.

Также убедитесь, что у вас просто нет незавершенной транзакции.:)

Я проводил несколько тестов и начал транзакцию, чтобы быть в безопасности, но так и не закрыл ее. Хотелось бы, чтобы ошибка была более явной, ну да ладно!

Недавно мы обновили NuGet-версию SqlClient (Microsoft.Data.SqlClient), в котором есть ошибка. Эта ошибка возникла во время существования цикла 1.x и уже исправлена. Исправление будет доступно в версии 2.0.0, недоступной на момент написания этой статьи. Доступен предварительный просмотр.

Вы можете ознакомиться с подробностями здесь:https://github.com/dotnet/SqlClient/issues/262

У нас были тяжелые времена Timeout expired/max pool reached Sqlexception. В качестве временного решения и для предотвращения перезапуска сервера или службы мы изменяемMAX SERVER MEMORY переменная в SQL Server (либо через SQL Managment Studio, либо через T-SQL):

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

Это временно решит проблему, пока она не повторится снова. В нашем случае мы подозреваем, что это связано с утечками соединений на уровне приложений.

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

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

у меня такая же ошибка в моей многопоточной программе, к которой одновременно подключено более 2000 пользователей. проблема возникла, когда я запускаю команду SELECT с более чем 5000 строк. эта команда заблокирована командой вставки. изменив SELECT * на SELECT Top(n) *, что n<5000 он исправляет

Возможно, вы забылиawaitаasyncзаявление? Вы получите аналогичное сообщение, если вашtaskв конечном итоге это занимает больше времени, чем когда ваш поток был прерван.

Как уже говорили другие, проблема может быть связана с ожидающей транзакцией. В моем случае мне пришлось отправить переменную DbTransaction в качестве параметра в методе ExecuteScalar , чтобы процедура выполнялась правильно.

До:

      ExecuteScalar(command)

После:

      ExecuteScalar(command, transaction)

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

Очевидно, что вы можете увеличить CommandTimeout для решения этой проблемы, но перед этим вы должны оптимизировать свой запрос, добавив индекс. Если вы выполняете запрос в Sql Server Management Studio, включая фактический план выполнения, то Sql Server Management Studio предложит вам соответствующий индекс. В большинстве случаев вы избавитесь от проблемы тайм-аута, если сможете оптимизировать свой запрос.

Другие вопросы по тегам