传递 jdbc 数据源与传递 Connection 对象 - 从 servlet 到 java 类

Posted

技术标签:

【中文标题】传递 jdbc 数据源与传递 Connection 对象 - 从 servlet 到 java 类【英文标题】:Passing jdbc datasource v/s passing the Connection object - From servlet to java class 【发布时间】:2012-02-15 23:14:23 【问题描述】:

我有一个处理 post/get 请求的主 Servlet。 我正在使用连接池(jdbc / mysql 和 glassfish v3),我的 servlet 代码是:

public class Controller extends HttpServlet 
private DataSource datasource;
@Override
public void init() throws ServletException 
      super.init();
     try 
        //Database Connection pooling:
        InitialContext ctx = new InitialContext();
        datasource = (DataSource)ctx.lookup("jdbc/MySQLPool");
      
      catch (Exception e) 
         e.printStackTrace();
       
   
private Connection getConnection() throws SQLException 
    return datasource.getConnection();
    
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException 
    Connection connection=null;
    try 
            connection = datasource.getConnection();
            Object obj=  cmdFactory.getInstance().getCommand(Cmd).execute(connection);
        

etc... 并在 servlet 的最后一个 finally 块中关闭连接

所以现在我将“连接”对象作为最后一行中的参数传递,以供其他(非 servlet)java 类通过应用程序的较低层使用。这是错的吗?传递数据源对象是否更好(然后在特定类中执行 datasource.getConnection())?或者是否有类似于 "getServletContext().getAttr(database)" 的东西可以在其他 java 类中用于获取此连接?

【问题讨论】:

【参考方案1】:

DataSource 允许获取 JDBC 连接(大部分时间来自连接池)。在 servlet 环境中,如果您两次请求到 DataSource 的连接,您将获得两个不同的连接。

因此传递 DataSource 没有意义:您希望调用链中的所有对象使用相同的连接,并在最后提交。

并且连接必须通过从 DataSource 中获取的方法在 finally 块中关闭,否则连接池会泄漏连接,您将很快耗尽可用连接。

【讨论】:

非常感谢 :) 是的,关于泄漏你是绝对正确的,谢谢你提醒我,因为我忘记了! 一个问题:您如何估算或计算,特定网络应用程序的连接池大小应该是多少?是否有类似的参考?这是我第一次使用连接池,我只是使用 glassfish 的默认参数 我取决于并发用户数,数据库实际支持的连接数,线程池中的线程数。您必须使用预期的并发用户数对您的应用程序进行负载测试,并查看最佳数量是多少。然后你必须验证现实是否符合你的期望。

以上是关于传递 jdbc 数据源与传递 Connection 对象 - 从 servlet 到 java 类的主要内容,如果未能解决你的问题,请参考以下文章

ThreadLocal(线程绑定)

如何传递连接代码?

JDBC事务处理

从 Spring 的 applicationContext xml 传递 hibernate.connection.datasource

JAVA中JDBC的基础使用

尝试使用 JDBC 模板传递列表并返回地图