【问题标题】:Is it necessary to get a a new Datasource from JNDI for every connection?是否有必要为每个连接从 JNDI 获取一个新的数据源?
【发布时间】:2017-12-05 19:23:58
【问题描述】:

查看来自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 对象的实例是一种反模式吗?

【问题讨论】:

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


    【解决方案1】:

    DataSource 对象可以被缓存并且是线程安全的,尽管 JNDI 应该进行了充分优化,使得从 JNDI 中获取 DS 的每个请求都可以忽略不计(同一个实例将从 JNDI 交回)。

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

    public class MyServlet extends HttpServlet {
    
      @Resource
      DataSource ds;
    
      public void processRequest() {
        try(Connection con = ds.getConnection()) {
          // ...
        }
      }
    
    }
    

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

    【讨论】:

      猜你喜欢
      • 2021-11-02
      • 2018-11-06
      • 2015-06-11
      • 2019-06-10
      • 2011-05-04
      • 2012-12-17
      • 1970-01-01
      • 2017-04-26
      • 2021-09-27
      相关资源
      最近更新 更多