数据库连接应该是单例吗?

时间:2011-06-28 14:02:30

标签: java design-patterns singleton

Java创建单例的最佳方法是什么? 数据库连接应该是单例(单例是否是自动线程安全的)?因为理论上DB不能同时被许多用户访问。

4 个答案:

答案 0 :(得分:25)

数据库连接通常不应该是单例。

有两个原因:

  1. 许多DB驱动程序不是线程安全的。使用单例意味着如果您有许多线程,它们将共享相同的连接。单例模式不会为您提供线程安全性。它只允许许多线程轻松共享“全局”实例。
  2. 就个人而言,我认为Singleton经常导致糟糕的设计:请参阅此帖(由其他人)http://tech.puredanger.com/2007/07/03/pattern-hate-singleton/
  3. 而不是这样做考虑数据库池。该池是共享的(如果需要,可以是单例)。当您需要进行数据库工作时,您的代码会这样做:

    getConnectioFromPool();
    
    doWork()
    closeConnection() // releases back to pool
    

    示例池库:

答案 1 :(得分:3)

最佳创建单例(截至今天)的方式是枚举单例模式(Java enum singleton

我怀疑,Singleton是必需的还是数据库连接的任何值。您可能想要一些延迟创建:在第一次请求和缓存时创建连接,进一步的请求将使用缓存的实例完成:

public ConnectionProvider {
  private Connection conn;

  public static Connection getConnection() {
    if (conn == null || conn.isClosed()) {
      conn = magicallyCreateNewConnection();
    }
    return conn;
  }
}

(非线程安全 - 如果需要,同步)

答案 2 :(得分:3)

  

Java创建的最佳方式是什么?   单身?

遵循设计模式创建指南。即私人建设者等。

  

数据库连接是否应该是单例   (作为单身人士,它是自动的   线程安全的)?

在许多情况下,创建数据库连接作为单例可能是一个糟糕的设计选择。仅在您确定不需要数据库并发时才使用它。如果您有多个用户同时登录,或者即使您的单个用户生成许多需要访问数据库的线程,那么数据库连接池也是更好的选择。您可以使用apache或tomcat db连接池。例如,在包

中定义了这些类
org.apache.commons.dbcp.*;

org.apache.tomcat.dbcp.dbcp.*;

其中dbcp代表数据库连接池。

使用连接池的最大原因是,平均而言,数据库访问(DML等)所需的时间远远小于创建连接然后关闭连接所需的时间。此外,请不要忘记在事务完成后关闭ResultSet,PreparedStatement和Connection变量。

  

因为理论上DB不可能   由许多用户访问   时间。

为什么不呢?在大多数情况下,DB意味着同时使用。您有这些数据库隔离级别 - READ_COMMITTED,READ_UNCOMMITTED,SERIALIZED等。 SERIALIZED是您的数据库成为单用户访问权限的情况。

答案 3 :(得分:2)

单身人士是一种模式 - 没有明确的创造方式,你只需遵循设计实践。

因此,如果您使用的数据库可以处理并发读/写(即MySQL),那么您不必担心线程安全问题。如果您使用的数据库不能很好地并发写入(SQLite),那么单个理论上应该可以正常工作。