是否需要为每个连接从 JNDI 获取一个新的数据源?

Is it necessary to get a a new Datasource from JNDI for every connection?

通过在每个连接请求上查询 JNDI 命名服务来查看 this it seems that it's appropriate to get a new DataSource 对象等高信誉用户的答案。例如。使用如下代码(为更简洁起见,改编自链接答案):

public class ConnectionManager{
       public static Connection getConnection() throws NamingException {
            Context initContext  = new InitialContext();
            Context envContext  = (Context)initContext.lookup("java:/comp/env");
            DataSource dataSource = (DataSource)envContext.lookup("jdbc/test");
            return dataSource.getConnection();
       }
}

这真的是建议的/惯用的方式吗?在我自己的一些 "ConnectionManager" 实用程序 类 中,我曾经将对 DataSource 对象的引用作为实例变量。除了 JBoss 管理员从管理控制台禁用并启用连接池,然后我的代码出现如下错误外,没有任何问题:

java.sql.SQLException: javax.resource.ResourceException: IJ000451: The connection manager is shutdown

那么,在 JDBC 中保留 DataSource 对象的实例是一种反模式吗?

DataSource 对象可以被缓存并且是线程安全的,尽管 JNDI 应该被充分优化以至于每次请求从 JNDI 中获取 DS 是微不足道的(相同的实例将从 JNDI 返回)。

例如,如果您在 Java EE 环境中工作,那么能够在 class 级别注入 DataSource 是规范标准,例如:

public class MyServlet extends HttpServlet {

  @Resource
  DataSource ds;

  public void processRequest() {
    try(Connection con = ds.getConnection()) {
      // ...
    }
  }

}

此外,跨多个线程共享 DataSource 对象是完全安全的。另一方面,跨多个线程共享 Connection 对象是一个很大的错误,因为根据规范它们不是线程安全的。