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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6507687/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-16 06:27:13  来源:igfitidea点击:

should a db connection be a singleton?

javadesign-patternssingleton

提问by spauny

What is the best way in Java to create a singleton? Should a DB connection be a singleton (being a singleton it's automatically thread-safe)? Because theoretical the DB can't be accessed by many users in the same time.

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

采纳答案by Dave

A DB connection should not normally be a Singleton.

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

Two reasons:

两个原因:

  1. many DB drivers are not thread safe. Using a singleton means that if you have many threads, they will all share the same connection. The singleton pattern does not give you thread saftey. It merely allows many threads to easily share a "global" instance.
  2. Personally, I think Singleton often leads to bad design: See this post (by somebody else) http://tech.puredanger.com/2007/07/03/pattern-hate-singleton/
  1. 许多数据库驱动程序不是线程安全的。使用单例意味着如果您有许多线程,它们将共享相同的连接。单例模式不会给你线程安全。它只是允许多个线程轻松共享一个“全局”实例。
  2. 就个人而言,我认为 Singleton 经常导致糟糕的设计:请参阅这篇文章(由其他人撰写)http://tech.puredanger.com/2007/07/03/pattern-hate-singleton/

Instead of doing this consider a database pool. The pool is shared (and could be a singleton if you wanted). When you need to do database work your code does this:

而不是这样做考虑一个数据库池。该池是共享的(如果您愿意,可以是单例)。当您需要进行数据库工作时,您的代码会执行以下操作:

getConnectioFromPool();

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

Sample Pool Libraries:

示例池库:

回答by Andreas Dolk

The bestway to create a singleton (as of today) is the enum singleton pattern (Java enum singleton)

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

I doubt, that a Singleton is necessary or of any value for a database connection. You probably want some lazy creation: a connection is created upon first demand and cached, further requests will be fullfilled with the cached instance:

我怀疑,对于数据库连接来说,单例是必要的还是有任何价值的。你可能想要一些懒惰的创建:在第一次请求时创建一个连接并缓存,进一步的请求将被缓存的实例填满:

public ConnectionProvider {
  private Connection conn;

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

(not thread safe - synchronize, if needed)

(不是线程安全的 - 如果需要,同步)

回答by jefflunt

Singletons are a pattern - there's no explicit way to create one, you just follow the design practice.

单例是一种模式 - 没有明确的创建方式,您只需遵循设计实践即可。

So, if you're using a database that can handle concurrent reads/writes (i.e. MySQL), you don't need to worry so much about thread safety. If you're using a DB that's doesn't do concurrent writes well (SQLite), then a singleton should theoretically work.

因此,如果您使用的是可以处理并发读/写的数据库(即 MySQL),则不必太担心线程安全。如果您使用的数据库不能很好地进行并发写入(SQLite),那么理论上应该可以使用单例。

回答by Basanth Roy

What is the best way in Java to create a singleton?

Java 中创建单例的最佳方法是什么?

Follow the design pattern creation guidelines. i.e private constructor, etc.

遵循设计模式创建指南。即私有构造函数等。

Should a DB connection be a singleton (being a singleton it's automatically thread-safe)?

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

creating a DB connection as a singleton might be a poor design choice in many scenarios. Use it only if you are sure that you don't need DB concurrency. If you have multiple users logged in at the same time, or even if your single user spawns many threads that need to access the DB, then a DB Connection pool is a better choice. You can use either apache or tomcat db connection pools. THese classes are defined for example in the package

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

org.apache.commons.dbcp.*;

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

where dbcp stands for database connection pooling.

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

The biggest reason for using a connection pool is that on average the time it takes for the DB access (DML etc) is much smaller than the time it takes to create a connection and then close the connection. Additionally, don't forget to close your ResultSet, PreparedStatement and Connection variables after the transaction is done.

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

Because theoretical the DB can't be accessed by many users in the same time.

因为理论上数据库不能被多个用户同时访问。

Why not? DB in most cases is meant to be used concurrently. You have these DB isolation levels - READ_COMMITTED, READ_UNCOMMITTED, SERIALIZED etc. SERIALIZED is the case where your DB becomes single user access.

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