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

时间:2017-12-05 19:23:58

标签: java jdbc database-connection datasource connection-pooling

查看来自this等高信誉用户的答案,似乎通过在每个连接请求上查询JNDI命名服务来获取新的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对象的实例是一种反模式吗?

1 个答案:

答案 0 :(得分:1)

DataSource对象可以被高速缓存并且是线程安全的,尽管JNDI应该足够优化,使得每个请求从JNDI中获取DS可以忽略不计(相同的实例将从JNDI返回)。

例如,如果您在Java EE环境中工作,那么它的规范标准就是能够在类级别注入数据源,例如:

public class MyServlet extends HttpServlet {

  @Resource
  DataSource ds;

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

}

此外,跨多个线程共享DataSource对象是完全安全的。另一方面,跨多个线程共享Connection对象是一个很大的错误,因为这些对于每个规范都不是线程安全的。