【问题标题】:SQL Server Express 2008, Joins, and Timeout Expired Error MessageSQL Server Express 2008、联接和超时已过期错误消息
【发布时间】:2013-05-09 04:05:51
【问题描述】:

我有一个执行相当多的连接的存储过程。查询虽然运行得非常快,大约 3 秒。我只是无法弄清楚每隔一段时间就会弹出以下错误。我将使用此查询的文档缓存一分钟,这样它就不会一遍又一遍地运行。我正在使用 Entity Framework 5,我的存储过程正在使用 CTE 进行分页。有什么线索或见解吗?

 System.Data.SqlClient.SqlException (0x80131904): Timeout expired.  The timeout period elapsed prior to completion of the operation or the server is not responding. ---> System.ComponentModel.Win32Exception (0x80004005): The wait operation timed out
   at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
   at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
   at System.Data.SqlClient.SqlDataReader.TryConsumeMetaData()
   at System.Data.SqlClient.SqlDataReader.get_MetaData()
   at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
   at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite)
   at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean asyncWrite)
   at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)
   at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method)
   at System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
   at System.Data.Common.DbCommand.ExecuteReader()
   at System.Data.Objects.ObjectContext.ExecuteStoreQueryInternal[TElement](String commandText, String entitySetName, MergeOption mergeOption, Object[] parameters)
   at System.Data.Objects.ObjectContext.ExecuteStoreQuery[TElement](String commandText, Object[] parameters)
   at System.Data.Entity.Internal.InternalContext.ExecuteSqlQuery[TElement](String sql, Object[] parameters)
   at System.Data.Entity.Internal.InternalContext.ExecuteSqlQueryAsIEnumerable[TElement](String sql, Object[] parameters)
   at System.Data.Entity.Internal.InternalContext.ExecuteSqlQuery(Type elementType, String sql, Object[] parameters)
   at System.Data.Entity.Internal.InternalSqlNonSetQuery.GetEnumerator()
   at System.Data.Entity.Internal.InternalSqlQuery`1.GetEnumerator()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at Tournaments.Data.Repositories.Games.GamesRepository.GetGamesPaged(IGamesCriteria criteria)

实体框架方法

 public PagedResult<GameComplex> GetGamesPaged(IGamesCriteria criteria)
        {
            var results = DataContext.Database.SqlQuery<GameComplex>("EXEC [Schema].[Database] @Page, @PageSize, @SortOrder, @SortDirection, @EventId, @DivisionId, @DivisionTeamId, @Date, @SearchToken, @MemberId",
                new SqlParameter("Page", criteria.Page),
                new SqlParameter("PageSize", criteria.PageSize),
                new SqlParameter("SortOrder", GetDataValue(criteria.SortOrder)), 
                new SqlParameter("SortDirection", GetDataValue(criteria.SortDirection)),
                new SqlParameter("EventId", GetDataValue(criteria.EventId)),
                new SqlParameter("DivisionTeamId", GetDataValue(criteria.DivisionTeamId)), 
                new SqlParameter("DivisionId", GetDataValue(criteria.DivisionId)), 
                new SqlParameter("Date", GetDataValue(criteria.Date)),
                new SqlParameter("SearchToken", GetDataValue(criteria.SearchToken)),
                new SqlParameter("MemberId", GetDataValue(criteria.MemberId))).ToList();

            return new PagedResult<GameComplex>
                       {
                           Page = criteria.Page,
                           PageSize = criteria.PageSize,
                           Total = results.Any(q => q != null) ? results.FirstOrDefault().Total : 0,
                           Results = results
                       };
        }

SQL Server 存储过程参数签名

ALTER PROCEDURE [Schema].[Database]
    @Page INT = 1,
    @PageSize INT = 10,
    @SortOrder NVARCHAR(100) = 'Id',
    @SortDirection VARCHAR(4) = 'ASC',
    @EventId INT = NULL,
    @DivisionId INT = NULL,
    @DivisionTeamId INT = NULL,
    @Date DATETIME = NULL,
    @SearchToken NVARCHAR(100) = NULL,
    @MemberId INT = NULL
AS

【问题讨论】:

    标签: sql-server entity-framework stored-procedures join timeout


    【解决方案1】:

    您可能需要调整命令超时。

    见:

    Set Command Timeout in entity framework 4.3

    How to set CommandTimeout for DbContext?

    编辑

    命令超时:

    http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand.commandtimeout.aspx

    连接超时:

    http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection.connectiontimeout.aspx

    编辑:

    另一个可能的问题是“参数嗅探”。

    http://blogs.msdn.com/b/queryoptteam/archive/2006/03/31/565991.aspx

    所以尝试其中一种参数嗅探解决方法:

    ALTER PROCEDURE [Schema].[Database]
        @Page INT = 1,
        @PageSize INT = 10,
        @SortOrder NVARCHAR(100) = 'Id',
        @SortDirection VARCHAR(4) = 'ASC',
        @EventId INT = NULL,
        @DivisionId INT = NULL,
        @DivisionTeamId INT = NULL,
        @Date DATETIME = NULL,
        @SearchToken NVARCHAR(100) = NULL,
        @MemberId INT = NULL
    AS
    
    Declare @PageCopyOf int
    Select @PageCopyOf = @Page
    
    
    Declare @PageSizeCopyOf int
    Select @PageSizeCopyOf = @PageSize
    
    Declare @SortOrderCopyOf NVARCHAR(100)
    Select @SortOrderCopyOf = @SortOrder
    
    Declare @SortDirectionCopyOf VARCHAR(4) 
    Select @SortDirectionCopyOf = @SortDirection
    
    Declare @EventIdCopyOf int
    Select @EventIdCopyOf = @EventId
    
    Declare @DivisionIdCopyOf int
    Select @DivisionIdCopyOf = @DivisionId 
    
    
    Declare @DivisionTeamIdCopyOf int
    Select @DivisionTeamIdCopyOf = @DivisionTeamId
    
    Declare @DateCopyOf DATETIME
    Select @DateCopyOf = @Date
    
    Declare @SearchTokenCopyOf  NVARCHAR(100)
    Select @SearchTokenCopyOf = @SearchToken
    
    Declare @MemberIdCopyOf int
    Select @MemberIdCopyOf = @MemberId
    

    然后它下面的所有内容都使用/消耗@XXXXXCopyOf 变量而不是原始变量(名称)。

    值得一试。

    【讨论】:

    • 命令超时对存储过程的工作方式是否相同?看上面的代码。
    • 在 ADO.NET 术语中....SqlCommand.Timeout 是在超时和“放弃”之前它将等待运行存储过程的确切时间。
    • 好的,我找到了命令对象并更新了它。如果这行得通,我会标记你的答案,因为它更有意义。
    • 如果这不起作用,请发布您的存储过程的签名。我会跟进一个参数嗅探建议。
    • 还在做,签名贴在上面。
    【解决方案2】:

    只是猜测,但查询仅在缓存时运行速度很快(3 秒)。否则,它需要更长的时间并超过您的服务器超时设置。由于 System.Data.SqlClient 正在引发异常,因此默认超时可能只有 15 秒。

    MSDN: "The default value is 15 seconds"

    或者,尝试 SQLCommand 对象的 CommandTimeout 属性,默认为 30 秒。

    CommandTimeout

    【讨论】:

    • 我有 180 秒的连接字符串,你认为这不是正确的地方吗?
    • 尝试 ConnectTimeout,不要在单词之间指定一个规范。从同一页面:“您可以使用 ConnectTimeout 或 Connection Timeout 关键字设置连接等待超时的时间”
    • 我只看到带有空格的示例,但我选择了“连接”而不是“连接”。我会看看这是否能解决问题,如果可以,我会将其标记为正确。
    • Connect Timeout=180 是等待“查找并与 sql server 对话”的时间......就像您尝试连接到 SqlServer 并为服务器/实例输入错误名称一样..它将尝试连接这么长时间........这不是命令超时。命令超时适用于您尝试的每个 cmd.SomeAction(例如 ExecuteNonQuery)。
    • 在链接页面的“备注”部分,在第一句话中,它说您可以使用 ConnectTimeout 或 Connection Timeout。第一个没有空格。
    猜你喜欢
    • 1970-01-01
    • 2012-05-26
    • 1970-01-01
    • 2023-03-04
    • 2014-09-07
    • 2012-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多