春季启动数据连接未发布

发布于 2025-02-11 15:13:29 字数 2481 浏览 1 评论 0原文

我使用XML文件配置了一个批处理作业。我创建了一个新的Spring Boot应用程序,并依赖于此批处理作业。本春季启动应用程序的目的是使用API​​(用于测试目的)运行批处理作业。 让我分享我的实施。

我面临的问题是,

<batch:job id="batch-job_update" parent="baseJob">
        <batch:step id="batch_update.step01">
            <batch:tasklet transaction-manager="transactionManager">
                <batch:chunk
                        reader="batchReader"
                        processor="batchProcessor"
                        writer="batchWriter"
                        commit-interval="1">
                </batch:chunk>
            </batch:tasklet>
        </batch:step>
    </batch:job>

在Spring Boot控制器中,我通过将此XML文件加载到上下文中,

ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("path/to/batch-job-config.xml");

Job job = context.getBean("batch-job_update, Job.class);
JobRepository jobRepository = context.getBean("jobRepositoryBeanName", JobRepository.class);
JobLauncher jobLauncher = context.getBean("jobLauncherBeanName", JobLauncher.class);
jobLauncherTestUtils.setJob(job);
jobLauncherTestUtils.setJobLauncher(jobLauncher);
jobLauncherTestUtils.setJobRepository(jobRepository);
JobParameters jobParameters = getJobParameters(jobParametersList);
JobExecution jobExecution = jobLauncherTestUtils.launchJob(jobParameters);

context.close();

我面临的问题是,在运行批处理时创建的DB连接未关闭,并且由于我是我AM使用大量测试用例运行此API,连接耗尽后,我会得到以下例外,

28-06-2022 10:01:38.476 [http-nio-7788-exec-3] ERROR org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/].[dispatcherServlet].log - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jobRepository': Invocation of init method failed; nested exception is org.springframework.jdbc.support.MetaDataAccessException: Could not get Connection for extracting meta-data; nested exception is org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection; nested exception is java.sql.SQLException: Cannot create PoolableConnectionFactory (FATAL: remaining connection slots are reserved for non-replication superuser connections)] with root cause
org.postgresql.util.PSQLException: FATAL: remaining connection slots are reserved for non-replication superuser connections

有人可以帮我吗?提前致谢

I have a batch job configured using an XML file. And I have created a new Spring boot application with dependency to this batch job. The purpose of this spring boot application is to run the batch job using an API (for testing purpose).
Let me share my implementation of the same.

batch-job-config.xml

<batch:job id="batch-job_update" parent="baseJob">
        <batch:step id="batch_update.step01">
            <batch:tasklet transaction-manager="transactionManager">
                <batch:chunk
                        reader="batchReader"
                        processor="batchProcessor"
                        writer="batchWriter"
                        commit-interval="1">
                </batch:chunk>
            </batch:tasklet>
        </batch:step>
    </batch:job>

In the spring boot controller, I am running the batch job by loading this XML file into the context

ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("path/to/batch-job-config.xml");

Job job = context.getBean("batch-job_update, Job.class);
JobRepository jobRepository = context.getBean("jobRepositoryBeanName", JobRepository.class);
JobLauncher jobLauncher = context.getBean("jobLauncherBeanName", JobLauncher.class);
jobLauncherTestUtils.setJob(job);
jobLauncherTestUtils.setJobLauncher(jobLauncher);
jobLauncherTestUtils.setJobRepository(jobRepository);
JobParameters jobParameters = getJobParameters(jobParametersList);
JobExecution jobExecution = jobLauncherTestUtils.launchJob(jobParameters);

context.close();

The issue I am facing is that the db connections created while running the batch are not closed, and since I am running this API with lot of test cases, after the connections are exhausted I am getting the following exception

28-06-2022 10:01:38.476 [http-nio-7788-exec-3] ERROR org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/].[dispatcherServlet].log - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jobRepository': Invocation of init method failed; nested exception is org.springframework.jdbc.support.MetaDataAccessException: Could not get Connection for extracting meta-data; nested exception is org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection; nested exception is java.sql.SQLException: Cannot create PoolableConnectionFactory (FATAL: remaining connection slots are reserved for non-replication superuser connections)] with root cause
org.postgresql.util.PSQLException: FATAL: remaining connection slots are reserved for non-replication superuser connections

Could anyone please help me with this one? Thanks in advance

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

南风起 2025-02-18 15:13:29

这是因为您正在为每个请求为API创建一个新的Spring应用程序上下文。您可以将批处理应用程序上下文添加到Spring Boot应用程序中,然后将作业和作业启动器注入控制器,类似:

@RestController
public class JobLaunchingController {

    @Autowired
    private Job job;

    @Autowired
    private JobLauncher jobLauncher;

    @RequestMapping(value = "/", method = RequestMethod.POST)
    @ResponseStatus(HttpStatus.ACCEPTED)
    public void launch(@RequestParam("name") String name) throws Exception {
        JobParameters jobParameters = new JobParametersBuilder()
                        .addString("name", name)
                        .toJobParameters();
        this.jobLauncher.run(job, jobParameters);
    }
}

这将使用主要应用程序上下文的同一数据库连接池关闭。

This is because you are creating a new Spring application context for each request to your API. You can add the batch application context to your Spring Boot app and inject the job and job launcher in your controller instead, something like:

@RestController
public class JobLaunchingController {

    @Autowired
    private Job job;

    @Autowired
    private JobLauncher jobLauncher;

    @RequestMapping(value = "/", method = RequestMethod.POST)
    @ResponseStatus(HttpStatus.ACCEPTED)
    public void launch(@RequestParam("name") String name) throws Exception {
        JobParameters jobParameters = new JobParametersBuilder()
                        .addString("name", name)
                        .toJobParameters();
        this.jobLauncher.run(job, jobParameters);
    }
}

This will use the same database connection pool of the main application context which will be closed correctly when your Boot app is shutdown.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文