【发布时间】:2019-09-13 17:45:50
【问题描述】:
MS sql 2014 后端(在同一台机器上)-Executereader times out (native error code: 258) @ second executereader() 在同一连接中。为什么会这样?
(不涉及大数据量,涉及的cmd字符串是正确的)
注意:如果所有 SELECT 都进入单独的连接,第二个总是超时并不重要。如果我使用 DataAdapter 来捕获数据也没关系....超时...见下文,感谢您的想法:
using (SqlConnection c = new SqlConnection(cString))
{
c.Open();
using (SqlCommand cmd = new SqlCommand(querystringPO, c))
{
cmd.Parameters.AddWithValue("@paramRecipe", productionOrderNo);
using (SqlDataReader rd = cmd.ExecuteReader())
{
dtRecipe = new DataTable();
dtRecipe.Load(rd);
rd.Close();
}
}
if (dtRecipe.Rows.Count > 0)
{
string querystringOpDefs = "SELECT * FROM ReferencedFieldsView_OperationDefinition WHERE RecipeID=@paramOpDef";
using (SqlCommand cmd1 = new SqlCommand(querystringOpDefs, c))
{
cmd1.Parameters.AddWithValue("@paramOpDef", dtRecipe.Rows[0].Field<int>("ID"));
using (SqlDataReader rd = cmd1.ExecuteReader())
{
dtOpDefs = new DataTable();
dtOpDefs.Load(rd);
rd.Close();
}
}
string querystringBOMItems = "SELECT * FROM ReferencedFieldsView_BomItem WHERE RecipeID=@paramBOMItem";
using (SqlCommand cmd2 = new SqlCommand(querystringBOMItems, c))
{
cmd2.Parameters.AddWithValue("@paramBOMItem", dtRecipe.Rows[0].Field<int>("ID"));
using (SqlDataReader rd = cmd2.ExecuteReader())
{
dtBOMItems = new DataTable();
dtBOMItems.Load(rd);
}
}
}
}
下面的例子:
异常:System.InvalidOperationException:服务器操作遇到异常---> System.Data.SqlClient.SqlException:执行超时。在操作完成之前超时时间已过或服务器没有响应。 ---> System.ComponentModel.Win32Exception:等待操作超时 --- 内部异常堆栈跟踪结束 --- 在 System.Data.SqlClient.SqlConnection.OnError(SqlException 异常,布尔 breakConnection,Action`1 wrapCloseInAction) 在 System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj,布尔调用者HasConnectionLock,布尔异步关闭) 在 System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior,SqlCommand cmdHandler,SqlDataReader dataStream,BulkCopySimpleResultSet bulkCopyHandler,TdsParserStateObject stateObj,Boolean & dataReady) 在 System.Data.SqlClient.SqlDataReader.TryConsumeMetaData() 在 System.Data.SqlClient.SqlDataReader.get_MetaData() 在 System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds,RunBehavior runBehavior,字符串 resetOptionsString,布尔 isInternal,布尔 forDescribeParameterEncryption,布尔 shouldCacheForAlwaysEncrypted) 在 System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior,RunBehavior runBehavior,布尔 returnStream,布尔异步,Int32 超时,任务和任务,布尔异步写入,布尔 inRetry,SqlDataReader ds,布尔 describeParameterEncryptionRequest) 在 System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior,RunBehavior runBehavior,布尔 returnStream,String 方法,TaskCompletionSource`1 完成,Int32 超时,Task& 任务,Boolean& usedCache,Boolean asyncWrite,Boolean inRetry) 在 System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior,RunBehavior runBehavior,布尔 returnStream,String 方法) 在 System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior 行为,字符串方法) 在 System.Data.SqlClient.SqlCommand.ExecuteReader()
【问题讨论】:
-
发布完整的异常,包括调用堆栈和任何内部异常。您可以使用
Exception.ToString()轻松获得。您甚至没有发布可以解释它是哪种超时的消息。不要只是发布消息,发布 full 异常 -
至于为什么会出现超时,如果是命令超时,一般是因为查询不好,缺少索引。修复它们的方法是修复查询并添加适当的索引。如果数据很多,无法优化,则应增加超时时间
-
视图名称表明您正在运行 BOM 查询。这些类似于分层查询,除非特别注意,否则可能会非常慢。实现它们的典型方法是使用递归,这很慢。或者,您可以将
Parent/ChildID关系替换为hierarchyid字段并获得非常 快速查询 -
使用 SQL Server Management Studio 并在 SSMS 上运行查询。 SSMS 中的错误消息比 c# 调试这些类型的问题要好 1000 倍。
-
那么你已经确定有一个锁,或者这是推测?您可以使用
sys.dm_os_waiting_tasks查看查询是否实际被阻止,以及原因。拥有本地服务器只能确定问题不在于网络;它仍然可以是执行计划。