Java 用于创建JasperReport后未释放池连接
我们已经在prod中使用了一个springbootweb应用程序。 最近,该公司要求将一些EOD对账报告作为不可编辑PDF生成 我们编译了一些Jasper报告,并开始使用以下代码生成报告:Java 用于创建JasperReport后未释放池连接,java,spring,jasper-reports,database-connection,connection-pooling,Java,Spring,Jasper Reports,Database Connection,Connection Pooling,我们已经在prod中使用了一个springbootweb应用程序。 最近,该公司要求将一些EOD对账报告作为不可编辑PDF生成 我们编译了一些Jasper报告,并开始使用以下代码生成报告: private void generatePdfReport(final Report report) throws SQLException, JRException { final JasperReport jasperReport = JASPER_REPORT_MAP.get(report);
private void generatePdfReport(final Report report) throws SQLException, JRException {
final JasperReport jasperReport = JASPER_REPORT_MAP.get(report);
if (jasperReport == null) {
throw new UnsupportedOperationException("The report is not supported: " + report.getName());
} else {
Connection connection = null;
try {
connection = dataSource.getConnection();
final JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, null, dataSource.getConnection());
final JRPdfExporter exporter = new JRPdfExporter();
exporter.setExporterInput(new SimpleExporterInput(jasperPrint));
exporter.setExporterOutput(new SimpleOutputStreamExporterOutput(report.getFormattedFilename() + Report.EXT_PDF));
exporter.setConfiguration(reportConfig);
exporter.setConfiguration(exportConfig);
exporter.exportReport();
log.info("PDF Report ({}) exported successfully!", report.getName());
} finally {
if (connection != null) {
log.info("about to close db connection");
connection.close();
connection = null;
}
}
}
}
这些报告运行良好,但在生成10个报告后,我们开始从Hitaki数据源收到超时异常,抱怨它无法在30秒内获得连接
Hitaki数据源的默认连接池大小为10,在Hitaki类中放置一些断点,我们可以看到所有10个连接在使用中都标记为。将数据源更改为commons dbcp并没有太大变化。这次没有超时,但在生成八份报告后,处理被无限期阻止。八是dbcp数据源的默认池大小
结论是这不是数据源问题,我们在jasper jars中放置了一些断点,并注意到结果集和创建的准备语句都已正确关闭
我们的Hitaki/DBCP数据源由spring TransactionWaredataSourceProxy实例包装。拿出包装纸什么也没变
最后,我用一个非常基本的数据源(显然不适合生产)替换了数据源,并且一切正常。请参见下面的代码,其中显示了我们尝试的内容:
@Bean
public DataSource dataSource() {
final String url = env.getProperty("database.url");
final String userName = env.getProperty("gmm.schema");
log.info("Creating DataSource for {}@{}", userName, url);
// final HikariDataSource dataSource = new HikariDataSource();
// final BasicDataSource dataSource = new BasicDataSource();
final SimpleDriverDataSource dataSource = new SimpleDriverDataSource();
dataSource.setUrl(url);
dataSource.setUsername(userName);
dataSource.setPassword(env.getProperty("gmm.password"));
// dataSource.setDriverClassName(env.getProperty("database.driver"));
dataSource.setDriverClass(oracle.jdbc.driver.OracleDriver.class);
return dataSource;
// return new TransactionAwareDataSourceProxy(dataSource);
}
现在我的问题是:
什么会导致这种行为,我应该如何修复或进一步调查。如果我们对报告作业进行注释,则不会出现连接问题,但另一方面,我不知道如何使用非常基本的数据源来解决此问题
作为Jasper报告的新手,我只希望我没有正确地使用它
先谢谢你 尝试将创建的连接对象传递给fillReport方法
connection = dataSource.getConnection();
final JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, null, dataSource.getConnection());
到
为我与DataSourceUtils合作干杯:
connection = DataSourceUtils.doGetConnection(dataSource);
JasperPrint jasperPrint = JasperFillManager.fillReport(report, params, connection);
在每次呼叫后使用简单连接,我有-1个空闲连接池。对于我来说,请尝试使用可用的资源:
JasperPrint jasperPrint;
try (Connection connection = dataSource.getConnection()) {
jasperPrint = JasperFillManager.fillReport(report, params, connection);
}
正如Rami指出的,您的代码有一个错误。请使用DataSourceUtils.getConnection
DataSourceUtils.releaseConnection(connection, dataSource);
JasperPrint jasperPrint;
try (Connection connection = dataSource.getConnection()) {
jasperPrint = JasperFillManager.fillReport(report, params, connection);
}