如何在 SpringBoot 下关闭 SpringBatch 的 JPA



我们有一个使用 Spring Integration 和 Spring Batch 的 Spring Boot 应用程序。 我们将文件放入轮询器中并进行处理。 此过程将记录插入数据库,然后读回记录,执行一些处理并写入文件。 假设有 10 条记录。 我们第一次读取 10 条记录和写入 10 条记录。 在不停止服务器的情况下,我们通过数据库上的SQL客户端删除所有记录,再次运行相同的文件,我们读取了10条记录,写入了20条记录。 我相信数据源正在进行一些 JPA 或缓存。 我们尝试关闭 JPA 和缓存的几个自动配置选项,但我们没有找到正确的配置选项来关闭缓存。

为问题添加更多细节。

基本上我们有带有文件处理程序的cron调度器。 这个句柄文件方法我们有以下内容。

public File handleFile(File file) throws Throwable {
JobParametersBuilder jobParametersBuilder = new JobParametersBuilder();
Job job = (Job) appContext.getBean("processInitialFileJob");
JobExecution jb = jobLauncher.run(job, jobParametersBuilder.toJobParameters());
....
}

我们可以对上面的代码做些什么来确保它有一个新的 JPA 会话或根本不使用 JPA 会话? 此作业每次都需要从数据库中读取,而不是数据库的缓存表示形式。

你正在使用Hibernate吗?休眠第一级缓存可能会给您带来问题。Hibernate管理会话本地的第一级缓存。因此,一旦您创建了一个会话并在该休眠中执行任何事务,就会在其中同步该会话。但是,当您在休眠之外对表进行任何更改时,休眠不会同步该表,直到在会话上调用刷新并且会话关闭。

为了确保这种情况不会发生,请在轮询器逻辑中尝试创建新的会话(如果是 JPA 则为 EntityManager),并为每个读/处理/写入周期关闭会话。

还要确保此hibernate.current_session_context_class未设置为"线程"。由于线程可以被轮询器重用,因此可以再次注入相同的休眠会话。

这最终不是Hibernate或JPA的问题,而是StringBuilder保留以前运行数据的问题。 我相信这需要设置为@JobScope这样它就不会在作业的不同执行中重复使用。