为什么我的SqlCommand在它应该是int时返回一个字符串?

Cha*_*ert 4 c# sql-server ado.net linq-to-sql

我有一个应该总是返回单个int 的查询.我现在记录它返回一个完全与它应该是无关的字符串.

我们已经获得了一些随机的FormatExceptions,我们已经跟踪了几个数据库查询.经过一些额外的日志记录后,我发现今天早上,下面的查询返回了字符串"gladiator".Website.PkID是一个i​​nt列,大部分时间都可以工作,但有时它会失败并且返回一个在那里(大于任何有效的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.

Cha*_*ert 9

在忽略了这个问题几个月后,随着交通量逐渐增加,它开始达到临界质量.我们增加了日志记录并发现了许多确定的实例,在这些实例中,在高负载下,完全不同的结果集将返回到不相关的查询.

我们在Profiler中查看了查询,并且能够看到错误的结果始终与相同的spid相关联,并且每个错误的结果总是在查询的实际sql语句后面的一个查询.这就像一个结果集被遗漏了,并且返回了spid中的下一个结果集(来自同一个池中的另一个连接).疯.

通过反复试验,我们最终找到了一些SqlCommand或LINQ查询,这些查询的SqlConnection在使用后没有立即关闭.相反,通过一些源于对LINQ连接的误解的草率编程,DataContext对象仅在请求结束时而不是立即处理(并且连接关闭).

一旦我们重构这些方法以立即关闭与C#"使用"块的连接(为下一个请求释放该池),我们就不再收到错误.虽然我们仍然不知道连接池会如此混淆的根本原因,但我们能够停止这种类型的所有错误.此问题已与我发布的另一个类似错误一起解决,在此处找到:导致"内部连接致命错误"的原因是什么?