【问题标题】:ASP.NET A static object to hold connection with a DB. Is it a good idea?ASP.NET 与数据库保持连接的静态对象。这是个好主意吗?
【发布时间】:2010-07-20 18:36:24
【问题描述】:

我想知道如果我将一个“持有”与数据库的连接的字段设置为静态字段(实体框架),这是否是 ASP.NET 项目中的一种好方法

public class DBConnector
{
    public static AdServiceDB db;
    ....
}

这意味着整个应用程序只有一个对象与数据库通信。我还想知道该对象是否会刷新数据库表中的数据更改,或者它不应该是静态的,我应该动态地创建连接。你怎么看?

【问题讨论】:

    标签: asp.net static


    【解决方案1】:

    使用 .NET 中的连接池,通常可以为每个请求创建一个新连接。我会评估每次创建一个新的性能,如果它不是瓶颈,那么避免使用静态方法。我之前尝试过,虽然我没有遇到任何问题,但似乎没有多大帮助。

    【讨论】:

      【解决方案2】:

      与来自多个用户的多个网页请求之间使用的数据库的单例连接存在很大的跨用户个人信息交叉污染的风险。不管性能影响如何,这是一个巨大的安全风险。

      如果您没有用户或个人信息,也许这目前不适用于您的项目,但请始终牢记这一点。随着时间的推移,数据库及其包含的信息往往会朝着更具体和更详细的方向发展。

      【讨论】:

      • 天哪,丹尼,是你!很想在这里见到你。你最近怎么样?很想与您取得联系,但无法从此处直接向您发送电子邮件。
      • 嘿希夫!你可以在网站地址或推特上私信我。
      • 这就像通过两个虚拟方法调用!我会这样做的
      【解决方案3】:

      这就是为什么您不应该在数据库连接中使用单例设计模式

      希望对你有帮助

      Is using a singleton for the connection a good idea in ASP.NET website

      【讨论】:

      • 您能否提供一个参考来支持您的断言,即“只有一个数据库连接实例总是一个好主意”?
      • 很抱歉我编辑了我的答案,我才意识到只有一个实例会有多糟糕。谢谢:)
      【解决方案4】:

      坏主意。除了由于未正确关闭连接等而可能犯的潜在错误外,访问静态对象还使得对代码进行单元测试变得非常困难。我建议使用实现接口的类,然后在需要的地方使用依赖注入来获取该类的实例。如果您确定希望它是单例,则可以在您的 DI 绑定中确定,而不是作为架构的基础点。

      【讨论】:

        【解决方案5】:

        我会说不。

        应在需要运行查询时创建数据库连接,并在完成查询并获取结果后进行清理。

        如果您使用单个静态实例来控制对数据库的所有访问,您可能会失去 .NET 提供的自动连接池(这可能会影响性能)。

        【讨论】:

          【解决方案6】:

          我认为建议是“经常刷新”。

          【讨论】:

            【解决方案7】:

            由于没有一个答案被标记为答案,我认为没有人真正解决过相关的问题或问题......

            在 ASP.NET 中,您有 Global 或 HttpApplication。这样做的方式是 IIS 将缓存您的“应用程序”的实例(即您的 Global 类的实例)。通常(IIS 中的默认设置)您最多可以拥有 10 个 Global 实例,IIS 将选择其中任何一个实例来满足请求。

            此外,请记住,在任何给定时刻都可能有多个请求。这意味着将使用您的 Global 类的多个实例。这些实例可能是先前实例化和缓存的实例,也可能是新实例(取决于您的 IIS 服务器所看到的负载)。

            IIS 还具有应用程序池和工作进程的概念。 Worker 进程将托管您的应用程序和 Global 类的所有实例(如前所述)。所以这转化为一个应用程序域(在 .NET 术语中)。

            只是在继续之前重新设置......

            您的 Global 类的多个实例将存在于您的应用程序的 Worker 进程中(在 IIS 中)。每一个都等待 IIS 调用以满足请求。 IIS 将选择这些实例中的任何一个。它们实际上是 IIS 缓存的线程,每个线程都有一个 Global 类的实例。当一个请求进来时,这些线程之一被调用来处理请求-响应周期。如果多个请求同时到达,则将调用多个线程(每个线程都包含一个 Global 类的实例)来满足每个请求。

            继续……

            由于每个应用程序域只有一个静态类的实例,因此您将有效地在所有(最多 10 个)Global 实例之间共享您的类的一个实例。这是一个坏主意,因为当多个同时请求到达您的服务器时,它们要么被阻塞(如果您的类的方法使用锁),要么线程将互相踩踏。换句话说,这种方法本质上不是线程安全的,如果您使用线程同步原语使其成为线程安全的,那么您将不必要地阻塞线程,对您的 Web 应用程序的性能和可伸缩性产生负面影响,而没有任何收益。

            真正的解决方案(我在所有 ASP.NET 应用程序中都使用它)是为每个 Global 实例创建一个 BLL 或 DAL 实例(视情况而定)。这将确保以下几点: 1. 多线程不是问题,因为 IIS 保证在任何给定时间每个 Global 实例都有一个请求-响应。所以你的代码本质上是线程安全的。 2. 在任何给定时刻,您最多只能有 10 个 BLL/DAL 实例启动并运行,确保您不会不断创建和处置(通常)大型对象的实例以满足每个请求,这在繁忙的网站上是巨大的 3. 由于上面的#2,你得到了非常好的性能。

            您必须确保您的 BLL/DAL 真正是无状态的,或者您必须在每个请求-响应周期开始时重置任何状态。您可以使用 Global 中的 BeginRequest 事件来完成您需要的操作。

            如果你走这条路,请务必阅读我的博客文章

            Instantiating Business Layers – ASP.NET

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2011-10-27
              • 1970-01-01
              • 2014-09-26
              • 1970-01-01
              • 1970-01-01
              • 2014-10-15
              • 2011-08-14
              • 2011-10-17
              相关资源
              最近更新 更多