Cha*_*ert 4 c# sql-server ado.net linq-to-sql
我有一个应该总是返回单个int 的查询.我现在记录它返回一个完全与它应该是无关的字符串.
我们已经获得了一些随机的FormatExceptions,我们已经跟踪了几个数据库查询.经过一些额外的日志记录后,我发现今天早上,下面的查询返回了字符串"gladiator".Website.PkID是一个int列,大部分时间都可以工作,但有时它会失败并且返回一个在那里(大于任何有效的WebsiteID)或随机字符串的int.
每个会话开始时会触发一次此特定查询.它没有使用共享连接,所以我很难理解它是如何得到这样的混合结果的.连接池中是否会出现某种损坏?
我不认为这个问题是孤立的.我也看到了来自LINQ查询的类似的FormatExceptions(因为意外的结果).我们也在同一时间发现了一些错误:
将请求发送到服务器时发生传输级错误.(提供程序:TCP提供程序,错误:0 - 远程主机强制关闭现有连接.
这可能是连接问题吗?或者我们可能在数据库服务器和Web服务器之间混淆了结果集?这真让我摸不着头脑.
违规查询:
public static int GetActiveWebSiteID(string storeID, string statusID)
{
int retval;
string sql = @"SELECT isnull(MAX(PkID),0) FROM WebSite
WHERE StoreID = @StoreID
AND WebSiteStatusID = @WebSiteStatusID";
SqlConnection conn = new SqlConnection(Settings.ConnString);
SqlCommand cmd = new SqlCommand(sql, conn);
cmd.CommandType = CommandType.Text;
cmd.Parameters.AddWithValue("@StoreID", (object)storeID ?? DBNull.Value);
cmd.Parameters.AddWithValue("@WebSiteStatusID", (object)statusID ?? DBNull.Value);
conn.Open();
using(conn)
{
var scalar = cmd.ExecuteScalar(); // <-- This value returned here should only ever be an int, but randomly is a string
retval = Convert.ToInt32(scalar);
}
return retval;
}
Run Code Online (Sandbox Code Playgroud)
直到最近,上述查询一直运作良好.我们现在在应用程序中有一堆额外的LINQ查询(不确定这是否有所不同).我们正在运行.Net 3.5.
在忽略了这个问题几个月后,随着交通量逐渐增加,它开始达到临界质量.我们增加了日志记录并发现了许多确定的实例,在这些实例中,在高负载下,完全不同的结果集将返回到不相关的查询.
我们在Profiler中查看了查询,并且能够看到错误的结果始终与相同的spid相关联,并且每个错误的结果总是在查询的实际sql语句后面的一个查询.这就像一个结果集被遗漏了,并且返回了spid中的下一个结果集(来自同一个池中的另一个连接).疯.
通过反复试验,我们最终找到了一些SqlCommand或LINQ查询,这些查询的SqlConnection在使用后没有立即关闭.相反,通过一些源于对LINQ连接的误解的草率编程,DataContext对象仅在请求结束时而不是立即处理(并且连接关闭).
一旦我们重构这些方法以立即关闭与C#"使用"块的连接(为下一个请求释放该池),我们就不再收到错误.虽然我们仍然不知道连接池会如此混淆的根本原因,但我们能够停止这种类型的所有错误.此问题已与我发布的另一个类似错误一起解决,在此处找到:导致"内部连接致命错误"的原因是什么?