bugfix> java > 投稿

すでにprodで使用しているスプリングブートWebアプリケーションがあります。 最近、企業は編集不可能なPDFとしてEOD調整レポートを作成するように要求しました。

Jasperレポートをいくつかコンパイルし、以下のようなコードを使用してレポートの生成を開始します。

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個のレポートを作成した後、30秒以内に接続を取得できないと訴えたHitakiデータソースからタイムアウト例外を取得し始めました。

Hitakiデータソースのデフォルトの接続プールサイズは10です。Hitakiクラスにいくつかのブレークポイントを置くと、10個の接続すべてが IN_USE としてマークされていることがわかります。 。データソースをcommons-dbcpに変更しても、それほど変わりませんでした。今回はタイムアウトしませんが、8つのレポートを生成した後、処理が無期限にブロックされました。 8は、dbcpデータソースのデフォルトのプールサイズです。

結論としては、データソースの問題ではなく、ジャスパーjarにいくつかのブレークポイントを置き、作成された結果セットと準備済みステートメントの両方が適切に閉じられていることに気付きました。

Hitaki/DBCPデータソースは、Spring TransactionAwareDataSourceProxyインスタンスによってラップされます。ラッピングを取り出しても何も変わりませんでした。

最終的に、データソースを非常に基本的なデータソース(明らかに本番には適さない)に置き換え、すべて正常に機能しました。試したことをコメントとして表示する以下のコードを参照してください。

   @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 Reportsを初めて使用する場合、適切に使用していないことを願っています。

前もって感謝します。

回答 1 件
  • 作成した接続オブジェクトをfillReportメソッドに渡してみてください。

    connection = dataSource.getConnection();
    final JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, null, dataSource.getConnection());
    
    

    connection = dataSource.getConnection();
            final JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, null, connection);
    
    

    乾杯

あなたの答え