gpt4 book ai didi

java - Java ComboPooledDataSource超出池大小,并且不重用

转载 作者:太空宇宙 更新时间:2023-11-04 09:48:12 25 4
gpt4 key购买 nike

我有以下代码被其他应用程序调用(无法更改)以读取数据库。
该方法经常在循环中调用,并使用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。
(如我所读过的,在高负载情况下,最终可能会被称为延迟……我想可能是这种情况)

但是,为什么仍然超出池大小?
在继续进行连接之前,如何限制该方法并阻塞该方法,直到再次可用?

最佳答案

在c3p0中进行连接轮询期间,您必须考虑一些选项。给出了以下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。在这里我添加了实际的实现

编辑(建立连接)

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

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


您如何获得EntityManager?

@PersistenceContext
private EntityManager entityManager;


希望这会帮助你。

谢谢 :)

关于java - Java ComboPooledDataSource超出池大小,并且不重用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55153643/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com