我的网站存在持续问题,它基本上会超时而且会死亡。我现在已经到了这一点,我必须将应用程序池设置为每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
答案 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)
只是一些常见的嫌疑人:
您是否处置了所有SqlCommand和读者?
您是在处理/关闭SqlConnection吗?
您的数据库是否能够处理负载?你有性能问题吗?
您帖子中的代码看起来不像是问题。
答案 2 :(得分:0)
我在这里看不到任何防范,以防止多次并发调用getter触发GetAllMembers
。当然,您一次只需要一个线程来加载该属性。某种lock()
似乎是必需的。
您应该确保刷新缓存的代码也使用相同的lock()
。
如果可以从多个服务器调用此代码,则还需要确保支持GetAllMembers
的任何数据库端程序逻辑(存储过程或来自客户端的动态SQL)有效且正确地处理多个并发读者。