我正在使用ASP.NET开发Web应用程序。我有一个名为“Sistema”的类,它使用Singleton模式。
创建Sistema实例时,将打开数据库连接并运行一个进程,该进程会加载一些静态信息供以后使用。这持续近2分钟。
private static Sistema instance;
private Sistema()
{
OpenDataBase();
LoadStaticInformation();
}
public static Sistema GetInstance()
{
if (instance == null)
{
instance = new Sistema();
}
return instance;
}
我保持与数据库的连接打开的原因是因为我正在使用db4o,这强烈暗示了这一点。以下是一些参考文献:
db4o best practice to query objects from db
Is it OK to open a DB4o file for query, insert, update multiple times?
Query regarding database connectivity in db4o
在我的Web App上,我有一个Master Page,通过检查Session变量来控制用户是否登录。如果此会话为空,则将用户发送到登录页面。
在登录页面上,我要做的第一件事就是检查“Sistema”的实例是否为空。如果是,则当用户点击“提交”按钮时,会显示一条消息,说“登录最多可能需要两分钟。请稍候”。如果它不为null,则不会显示任何消息,因为登录操作只需几秒钟。
用户告诉我,在通过系统时,有时会将它们发送回登录页面,当他们尝试登录时,会显示“登录最多需要两分钟”的消息。登录确实需要一段时间。
它们被发送回登录页面的事实意味着Session变量丢失,显示的消息意味着“Sistema”的实例也为空。
为了确定发生这种情况的原因,我创建了一个网页,当Sistema实例检测到为空时,会向我发送一封电子邮件。我想如果我能够知道这发生的时间,我可能会发现发生了什么。
这个网页非常简单。它每10分钟运行一次,检查Sistema的实例是否为空。如果是,则发送电子邮件并创建Sistema实例。
bool isInstanceNull = Sistema.IsInstanceNull();
if (isInstanceNull)
{
String emailTo = "...";
String emailContent = "...";
Functions.SendMail(emailTo, "Sistema is null", emailContent, "");
Sistema.GetInstance();
Functions.SendMail(emailTo, "Sistema has been created", emailContent, "");
}
我发现的唯一一件事就是它不是在特定的时间发生的。例如,上周它发生在晚上7点左右,但今天它发生在凌晨2点。
关于会话超时,我在后面的代码中使用了一个解决方案:http://www.beansoftware.com/ASP.NET-Tutorials/Keep-Session-Alive.aspx。
对于为什么会发生这种情况的任何建议?
答案 0 :(得分:0)
应用程序池有一个属性,使其每N分钟自动回收一次(默认为1740,或每29小时。)将此值设为零以禁用回收。该物业是(在IIS7上)在“回收”标题下,被称为“常规时间间隔(分钟)”
除此之外,您应该立即始终关闭连接,并且在ASP.NET中根本不使用static
连接(当默认启用Connection-Pooling时)。
我之所以提到它是因为:
private static Sistema instance;
private Sistema()
{
OpenDataBase();
LoadStaticInformation();
}
答案 1 :(得分:0)
您不应该保持与数据库的连接打开。通常会为每个请求打开一个新连接。也许数据库有时会判断它有太多用户或连接打开的时间太长,因此它会关闭连接并导致对象崩溃。与数据库的开放连接也存在安全风险。
虽然我不是100%肯定...
您应该将连接到数据库的内容移到某种查询执行方法。同时加载这样一团数据似乎是不明智的,你不能在后台进行,或者只加载用户当时需要看到的信息吗?