Java ComboPooledDataSource超出了池大小,不会重用

问题描述 投票:1回答:1

我有以下代码被其他应用程序调用(我无法更改)从数据库中读取。 经常在循环中调用该方法并对DB进行DOS操作。 在数据库中,我可以看到有许多连接被打开...增加到几百...而且由于负载导致数据库崩溃。

// Called in a loop
private <T> T execute(String query, PostProcessor<T> postProc, PreProcessor preProcs) throws OperationFailedException {
    try (Connection conn 
            = Objects.requireNonNull(dataSourceRef.get(), "No Connection").getConnection();
         PreparedStatement smt = conn.prepareStatement(query)) {
        preProc.process(smt);
        return postProc.process(smt.executeQuery());
    } catch (SQLException e) {
        throw new OperationFailedException(e.getMessage(), e);
    }
}

日期源在之前被初始化...

// class variable
// AtomicReference<PooledDataSource> dataSourceRef = new AtomicReference<PooledDataSource>();

// Init method
ComboPooledDataSource cpds = new ComboPooledDataSource();
cpds.setDriverClass(config.getConnectionDriver());
cpds.setJdbcUrl(config.getConnectionString());
cpds.setUser(config.getConnectionUser());
cpds.setPassword(config.getConnectionPassword());
// cpds.setMaxPoolSize(10);
dataSourceRef.getAndSet(cpds); 

我的问题为什么会发生这种情况。 我认为由于池不是每个查询都应该使用新的连接。同样通过设置最大池大小,这不起作用。

我尝试使用try-catch-finally构建并在使用后关闭stm和conn。 (正如我在某处看到的那样,在高负载情况下最终可能被称为延迟...我可能就是这种情况)

但仍然为什么游泳池大小超过?在继续之前,如何在连接可用之前限制并阻止该方法?

java datasource limit connection-pooling c3p0
1个回答
0
投票

在c3p0中的连接池期间,您必须考虑一些选项。这些是在qazxsw poi文件下面给出的:

application.property

在这里,db.driver: oracle.jdbc.driver.OracleDriver // for Oracle db.username: YOUR_USER_NAME db.password: YOUR_USER_PASSWORD db.url: DATABASE_URL minPoolSize:5 // number of minimum poolSize maxPoolSize:100 // number of maximum poolSize maxIdleTime:5 // In seconds. After that time it will realease the unused connection. maxStatements:1000 maxStatementsPerConnection:100 maxIdleTimeExcessConnections:10000 是主要观点。它定义了释放未使用连接的秒数。它排在第二位。

另一个是maxIdleTime。它定义了在空闲模式下它将保持多少连接。

另一个是minPoolSize。它定义了在加载模式下它将保持的最大连接数。

现在,你如何配置maxPoolSize?这是代码:

ComboPooledDataSource

有关详细信息,请查看@Bean public ComboPooledDataSource dataSource(){ ComboPooledDataSource dataSource = new ComboPooledDataSource(); try { dataSource.setDriverClass(env.getProperty("db.driver")); dataSource.setJdbcUrl(env.getProperty("db.url")); dataSource.setUser(env.getProperty("db.username")); dataSource.setPassword(env.getProperty("db.password")); dataSource.setMinPoolSize(Integer.parseInt(env.getProperty("minPoolSize"))); dataSource.setMaxPoolSize(Integer.parseInt(env.getProperty("maxPoolSize"))); dataSource.setMaxIdleTime(Integer.parseInt(env.getProperty("maxIdleTime"))); dataSource.setMaxStatements(Integer.parseInt(env.getProperty("maxStatements"))); dataSource.setMaxStatementsPerConnection(Integer.parseInt(env.getProperty("maxStatementsPerConnection"))); dataSource.setMaxIdleTimeExcessConnections(10000); } catch (PropertyVetoException e) { e.printStackTrace(); } return dataSource; } 。这里我添加了实际的实现

编辑(获取连接)

您可以使用以下方式获得连接:

this thread

你如何获得EntityManager?

Session session = entityManager.unwrap(Session.class);
session.doWork(connection -> doSomeStuffWith(connection));

希望这会帮助你。

谢谢 :)

© www.soinside.com 2019 - 2024. All rights reserved.