这段代码会杀了我的服务器吗?

时间:2010-10-18 17:38:14

标签: c# performance properties timeout thread-safety

我的网站存在持续问题,它基本上会超时而且会死亡。我现在已经到了这一点,我必须将应用程序池设置为每5分钟自动回收一次,但即使这样也失败了,因为我刚从工作中恢复过来,而我的电子邮件收件箱中有4000封电子邮件全部都是相同的错误。

System.Data.SqlClient.SqlException:超时已过期。操作完成之前经过的超时时间或服务器没有响应。

今天早上我尝试了一个测试,我在连接字符串上禁用了池,这也没有用。

现在我想也许这不是泄漏连接的问题,我之前已经完成了所有这些,我认为这可能与我网站核心的静态属性有关

这是其中之一

public static List<Member> AllMembers
{
    get
    {
        if (HttpRuntime.Cache["Members"] != null)
        {
            return (List<Member>)HttpRuntime.Cache["Members"];
        }
        else
        {
            GetAllMembers();
            return (List<Member>)HttpRuntime.Cache["Members"];
        }
    }
}

只要我想要一个成员列表就会调用它,你可以看到如果它为null,它会填充缓存,它将使用数据库,如果它不为null,那么它将返回缓存对象。我也有SQLCacheDependancy,它将清除这些缓存对象,因此它将再次填充它们。所以这个属性被称为ALOT。

现在这是一个Web应用程序,因为我的流量一直在增加其染色,

我的财产能成为原因吗?

非常感谢任何帮助

Truegilly

3 个答案:

答案 0 :(得分:6)

假设你正确处理了所有事情,我有另一种解释:

如果缓存为空/过期且多个页面同时尝试调用AllMembers,则每个页面可能最终同时调用GetAllMembers(),从而减​​慢数据库查询速度。如果呼叫开始超时,这可能会开始恶性循环。

您可以在代码周围放置lock,因此每个属性只能进行一次数据库查询。我可以通过以下方式进行设置:

private static object _allMembersLock = new object();
public static List<Member> AllMembers
{
    get
    {
        lock (_allMembersLock)
        {
            List<Member> members = (List<Member>)HttpRuntime.Cache["Members"];
            if (members == null)
            {
                members = GetAllMembers();
                HttpRuntime.Cache["Members"] = members;
            }
            return members;
        }
    }
}

答案 1 :(得分:1)

只是一些常见的嫌疑人:

  1. 您是否处置了所有SqlCommand和读者?

  2. 您是在处理/关闭SqlConnection吗?

  3. 您的数据库是否能够处理负载?你有性能问题吗?

  4. 您帖子中的代码看起来不像是问题。

答案 2 :(得分:0)

我在这里看不到任何防范,以防止多次并发调用getter触发GetAllMembers。当然,您一次只需要一个线程来加载该属性。某种lock()似乎是必需的。

您应该确保刷新缓存的代码也使用相同的lock()

如果可以从多个服务器调用此代码,则还需要确保支持GetAllMembers的任何数据库端程序逻辑(存储过程或来自客户端的动态SQL)有效且正确地处理多个并发读者。