【问题标题】:How singleton is used to manage database connection?单例如何用于管理数据库连接?
【发布时间】:2011-04-07 03:50:38
【问题描述】:

这可能是一个非常古老、被多次问到的问题。但是我找不到合适的答案,所以再问一次。

对于数据库连接,我们总是使用单例对象。当数据库被成千上万的用户访问时,性能如何保持?我的意思是如果每秒有数千个请求,由于我们使用单例,如何管理数据库连接?数据库请求是否序列化?还是在这些情况下不使用单例?

我知道这是一个愚蠢的问题,但我很困惑。如果有人能提供一些参考阅读链接,那就太好了。

谢谢。

【问题讨论】:

  • 为什么和谁说For the database connections, we always use a singleton object,真正的问题是什么?尝试说明您要解决的问题?

标签: java database design-patterns database-design singleton


【解决方案1】:

我不确定您是否将普通单例与服务定位器的使用混淆了。它们都是设计模式。应用程序使用服务定位器模式来确保有一个类负责获取和提供对数据库、文件、JMS 队列等的访问。

大多数服务定位器都是作为单例实现的,因为不需要多个服务定位器来完成相同的工作。此外,缓存从第一次查找中获得的信息,供服务定位器的其他客户端使用。

顺便说一下,关于

的论点

“这是为了确保您的数据库始终只有一个活动连接”

是虚假和误导性的。如果长时间处于非活动状态,连接很可能会被关闭/回收。因此,不赞成缓存与数据库的连接。这个论点有一个偏差。只要您使用相同的上下文,即在相同的 HTTP 请求或用户请求中(以适用者为准),就鼓励“重用”从连接池获得的连接。从性能的角度来看,这样做很明显,因为建立新的连接可能是一项昂贵的操作。

【讨论】:

    【解决方案2】:

    我推荐使用连接池
    http://www.java2s.com/Code/Java/Database-SQL-JDBC/PooledConnectionExample.htm

    【讨论】:

      【解决方案3】:

      即使您没有提供有关会话/事务/ORM 的任何内容,我认为您的问题来自 Hibernate、JPA 或其他 ORM 背景。

      因此,要发生任何事务,我们都需要一个 entityManager 或会话。可以为每个事务创建这些会话。

      现在通过使用工厂模式,我们可以得到尽可能多的相似对象......但是工厂本身应该是单例的。所以在 DB 操作中, entityManagerFactory 或 sessionFactory 对象被保存为单例。

      仔细想想,它是有道理的,因为毕竟 sessionFactory 代表一个配置(数据库、用户 ID、密码、连接池大小、缓存等)。执行数据库事务所需的不是工厂,而是工厂创建的对象(会话)。这些你可以拥有尽可能多的。但是,如果您有多个工厂,则无需创建相同(相似)的对象。

      我们在普通 jdbc 和 ORM 中使用连接池。

      【讨论】:

        【解决方案4】:

        如果您创建单例的数据库连接是无状态的(它应该是,或者至少应该是不可变的),那么它非常简单。

        当成千上万的用户同时访问您的 Web 应用程序时,实际上有数千个线程,每个用户一个。每个线程都有自己的程序计数器,用于跟踪当前正在处理的指令线程。当一个线程访问你的单例的公共方法时,例如myDBConnectionManager.getConnection(),它将开始执行其中指定的指令。因此,它实际上是一个线程,它通过读取myDBConnectionManager.getConnection()方法中指定的指令来创建数据库连接。单例的方法只是指导线程做什么的手册。

        这样,您的应用程序可以使用单例同时创建数百万个连接,只要它能够同时创建数百万个线程。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-07-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-09-25
          • 2013-07-11
          • 1970-01-01
          相关资源
          最近更新 更多