0

我正在使用 ASP.NET 开发一个 Web 应用程序。我有一个名为“Sistema”的类,它使用单例模式。

创建 Sistema 实例时,会打开数据库连接并运行一个进程,该进程会加载一些静态信息以供以后使用。这持续了将近 2 分钟。

private static Sistema instance;
private Sistema()
{
    OpenDataBase();
    LoadStaticInformation();
}

public static Sistema GetInstance()
{
    if (instance == null)
    {
        instance = new Sistema();
    }
    return instance;
}

我保持与数据库的连接打开的原因是因为我使用的是 db4o,这强烈暗示了这一点。以下是一些参考资料:

从 db 查询对象的 db4o 最佳实践

是否可以多次打开 DB4o 文件进行查询、插入、更新?

查询有关 db4o 中的数据库连接性

在我的 Web 应用程序上,我有一个母版页,通过检查 Session 变量来控制用户是否登录。如果此 Session 为空,则将用户发送到登录页面。

在登录页面上,我要做的第一件事是检查“Sistema”的实例是否为空。如果是,那么当用户点击提交按钮时,会显示一条消息,上面写着“登录可能需要最多两分钟。请稍候”。如果它不为空,则不会显示任何消息,因为登录操作只需几秒钟。

用户告诉我,在通过系统时,他们有时会被送回登录页面,当他们尝试登录时,会显示“登录可能需要最多两分钟”的消息,并且确实需要登录一会儿。

它们被发送回登录页面的事实意味着会话变量丢失,并且正在显示的消息意味着“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 。

关于为什么会发生这种情况的任何建议?

4

2 回答 2

0

应用程序池具有使其每 N 分钟(默认为 1740 或每 29 小时)自动回收的属性。将其设为零以禁用回收。该属性位于“回收”标题下(在 IIS7 上),称为“常规时间间隔(分钟)”

在此处输入图像描述

除此之外,您应该始终立即关闭连接,并且在 ASP.NET 中根本不使用static连接(当默认启用连接池时)。

我提到它是因为:

private static Sistema instance;
private Sistema()
{
    OpenDataBase();
    LoadStaticInformation();
}
于 2012-09-26T13:55:56.420 回答
0

您不应保持与数据库的连接处于打开状态。通常,每个请求都会打开一个新连接。也许数据库有时会决定它有太多用户或连接打开时间过长,结果它关闭了连接并且您的对象崩溃了。与数据库的开放连接也是一种安全风险。

不过,我不是100%确定这一点......

您可能应该将连接到数据库向下移动到某种查询执行方法。此外,一次加载这样一大堆数据似乎是不明智的,您不能在后台执行此操作还是仅加载用户当时需要查看的信息?

于 2012-09-26T13:59:04.597 回答