【问题标题】:DBCP Connection poolingDBCP 连接池
【发布时间】:2019-03-03 11:31:21
【问题描述】:

请问下面的代码是否可以正确使用连接池(DBCP)?

我提供 BasicDataSource 的实用程序类如下(几乎与 apache 示例相同)

public class DatabaseUtility {

    private static BasicDataSource dataSource;

    public static BasicDataSource getDataSource(Properties prop) {

        if (dataSource == null)
        {
            BasicDataSource ds = new BasicDataSource();
            ds.setUrl("jdbc:oracle:thin:@"+ prop.getProperty("db") + ":" + prop.getProperty("dbPort") + "/" + 
                    prop.getProperty("dbService"));
            ds.setUsername(prop.getProperty("dbUser"));
            ds.setPassword(prop.getProperty("dbPassword"));


            ds.setMinIdle(5);
            ds.setMaxIdle(10);
            ds.setMaxOpenPreparedStatements(100);

            dataSource = ds;
        }
        return dataSource;
    }

然后我将上面的内容用作:

public class MyClass {

    public static boolean isNew(Properties prop, String label) {

        Connection connection = null;
        PreparedStatement ps = null;

        try {
            BasicDataSource dataSource = DatabaseUtility.getDataSource(prop);
            connection = dataSource.getConnection();
            ps = connection.prepareStatement("Select * from my_table where LABEL = CAST( ? AS CHAR(35))");
            ps.setString(1, label);
            if (ps.executeQuery().isBeforeFirst()) {
                return false;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (ps != null)
                    ps.close();
                if (connection != null)
                    connection.close();
            } catch (SQLException e) {
                System.out.println("Error while closing resource :");
                e.printStackTrace();
            }
        }
        return true;
    }
}

Class MyClass 可能被多个衍生线程使用。 我没有看到此代码的任何潜在问题?

非常感谢

【问题讨论】:

    标签: java jdbc connection-pooling dbcp


    【解决方案1】:

    如果多个不同的线程第一次调用DatabaseUtility.getDataSource,您可能会遇到问题。您最终可能会得到多个数据源实例。阅读此链接以了解线程安全的惰性单例初始化:https://www.geeksforgeeks.org/java-singleton-design-pattern-practices-examples

    【讨论】:

    • 所以你基本上建议只更改DatabaseUtility 类中的方法声明,如下所示(例如使其同步?)public synchronized static BasicDataSource getDataSource(Properties prop) {...
    • @funkyjelly 制作方法synchronized 是性能最差的解决方案。我最好更喜欢持有者类成语(提供的链接中的 Bill Pugh Singleton 实现)
    • 在检查了一下之后,BasicDataSource 似乎是线程安全的,因为(几乎)它的所有变量都是同步读/写的。方法。 issues.apache.org/jira/browse/DBCP-285那么你建议的这些措施真的需要吗?
    • @funkyjelly 我指出的问题可能在两个线程同时调用BasicDataSource getDataSource() 时发生。两者都将看到 datasource == null 并将创建两个 BasicDataSource 实例
    【解决方案2】:

    如果您切换到HikariCP 池,将自动处理连接验证设置。看看池中的一些陷阱,例如:

    【讨论】:

    • 根据 DBCP 文档,testOnBorrow 默认为 true。您是否看到任何其他可能缺少的关键配置?如果我没记错的话,我应该很好地使用默认设置..
    • @funkyjelly 你是对的,删除了这部分答案。我不确定新的 2.5+ DBCP 与 HikariCP 相比如何。在旧版本中,DBCP 存在一些问题,我添加了几个链接来突出问题。
    猜你喜欢
    • 2012-12-22
    • 2017-04-19
    • 1970-01-01
    • 1970-01-01
    • 2012-07-03
    • 2015-03-28
    • 2013-01-06
    • 2012-07-06
    相关资源
    最近更新 更多