【问题标题】:Managing pooling datasource in Java web app with singleton class, Tomcat, C3P0使用单例类、Tomcat、C3P0 在 Java Web 应用程序中管理池数据源
【发布时间】:2012-02-16 10:55:28
【问题描述】:

我有一个在 Blackboard 学习软件中运行的 Java Web 应用程序,它使用 Tomcat 5.5。 该应用程序连接到外部数据库。

我无权在 Blackboard 服务器上声明数据源,因此我尝试将所有内容打包到 Web 应用程序中。尽管在使用后仔细关闭了所有结果集、语句和连接,但我的基于公共资源的池方法连接不足时遇到了问题。 我现在正在切换到 C3P0 池方法,但我不确定我的一般方法是否正确。

我正在使用单例类来创建数据源,目的是最大限度地减少实现连接池的数据源的创建和销毁。以下课程应该清楚地说明这一点。这是一种合理的方法,还是可能导致我之前的连接用尽问题?

谢谢。

编辑。更新了问题以阐明单例方法的目的。我试图避免在每次需要数据库连接时创建数据源。这似乎抵消了连接池的好处。

数据源类:

import java.beans.PropertyVetoException;
import java.sql.*;
import javax.sql.*;
import javax.naming.*;
import com.mchange.v2.c3p0.*;

public class MyDataSource {

private static MyDataSource mds = new MyDataSource();
public static DataSource ds;

private MyDataSource() {
    try {
        ds = getDataSource();
    } catch (NamingException e) {
        e.printStackTrace();
    }
}

public static MyDataSource getInstance(){
    return mds;
}

public Connection getConnection() throws SQLException, NamingException {
    Connection myConnect = ds.getConnection();
    return myConnect;
}

private DataSource getDataSource() throws NamingException {

    ComboPooledDataSource cpds = new ComboPooledDataSource(); 
    try {
        cpds.setDriverClass( "com.mysql.jdbc.Driver" );
    } catch (PropertyVetoException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    cpds.setJdbcUrl( "jdbc:mysql://195.195.xx.xx:3306/dbName" ); 
    cpds.setUser("lemmy"); 
    cpds.setPassword("xxx");
    cpds.setMaxIdleTime(180);
    cpds.setMaxPoolSize(100);       
    return cpds;
}
 }

连接类:

import java.sql.*;
import javax.sql.*;
import javax.naming.*;

public class DbConnection {

public Connection c;

public DbConnection() throws NamingException, SQLException {
    c = getConnection();
}

public Connection getConnection() throws SQLException, NamingException {        
    Connection myConnect = MyDataSource.getInstance().getConnection();
    return myConnect;       
}

public void close(){
    JDBCUtils.close(this.c);
}
}

关闭连接等

import java.sql.*;

public class JDBCUtils {

static public void close (ResultSet rs) {
    try { if (rs!=null) rs.close(); } catch (Exception e) {}
    }

  //  Works for PreparedStatement also since it extends Statement.
  static public void close (Statement stmt) {
    try { if (stmt!=null) stmt.close(); } catch (Exception e)   {}
    }

  static public void close (java.sql.Connection conn) {
    try { if (conn!=null) conn.close(); } catch (Exception e) {}
    }   

}

示例用法:

    String myQuery = null;
    DbConnection myConnect = null;
    Statement myStatement = null;
    ResultSet rs = null;

    try {
       myConnect = new DbConnection();
        myStatement = myConnect.c.createStatement();

                // Do stuff here

        }catch (SQLException e) {
    out.println("SQL Error: "+e);
    } finally {
        JDBCUtils.close(rs);
        JDBCUtils.close(myStatement);
        myConnect.close();
    }

【问题讨论】:

    标签: java singleton datasource connection-pooling c3p0


    【解决方案1】:

    您可能想查看 spring 框架中的JdbcTemplate。您可以单独使用它,因为 Spring 声称提供了许多帮助程序类。这简化了连接/语句/结果集嵌套问题。它还可以更简单地处理查询。

    我知道出于学习目的你可能不会使用 JdbcTemplate,但类设计很有趣。

    关于池化,@duffymo 已经给出了答案。

    【讨论】:

    • 谢谢,我会看看。我仍然不清楚我是否在现有方法的错误轨道上。我能找到的所有示例都使用 Web 服务器上的数据源集。
    • 我找到了这个例子,这是一个与静态数据源类似的方法:stackoverflow.com/questions/1458693/…
    • 如果你只是在寻找确认,你来这里做什么?
    • @duffymo :正如我在对 Joop 的有用答案的回复中指出的那样,原始问题仍未得到解答。因此,我为其他有兴趣找到问题答案的人提供了一些背景信息。我不是在寻找确认。如果你没有什么建设性的东西要补充,你来这里做什么?
    • 嗨 Lemmy,我会在一周中的每一天都将我的代表与您的代表放在一起。看看那个,乔普指出我的回答是中肯的。在我看来,您正在寻找确认。
    【解决方案2】:

    我认为这在各方面都是错误的想法。

    您希望连接池中有多个连接。让池管理生命周期;它将为每个请求分摊创建成本。

    单例意味着每个请求一个请求。这对我来说毫无意义。

    您的应用应以这种方式使用连接:每个请求一个。获取它,使用它,在单个方法的范围内将它返回到池中。这样会更好地扩展。您也可以编写更少的代码。将其设置为 JNDI 数据资源,一切顺利。

    【讨论】:

    • 单例表示一个数据源。但是数据源提供了多个连接。还是我错了?
    • 这个想法是防止每次需要数据库连接时都实例化一个新的数据源,并确保一个数据源与其连接池一起使用。
    • 你在这里重新发明了一个轮子。我同意 Joop Eggen 的观点:Spring 的 SimpleJdbcTemplate 比以往任何时候都做得更好。我不会自己写。
    猜你喜欢
    • 2014-02-09
    • 2023-03-20
    • 2013-03-26
    • 2023-03-27
    • 2016-03-04
    • 1970-01-01
    • 2019-10-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多