我在读取大型 CSV 文件(几百万条记录)并将记录从中保存到数据库时遇到了 Spring Batch 作业的问题。该作业FlatFileItemReader用于读取 CSV 并将JpaItemWriter读取和处理的记录写入数据库。问题是JpaItemWriter在将另一块项目刷新到数据库并且作业以OutOfMemoryError.我已经通过扩展JpaItemWriter和覆盖 write 方法解决了这个问题,以便它EntityManager.clear()在编写一堆之后调用,但我想知道 Spring Batch 是否已经解决了这个问题并且问题的根源在于作业配置。如何以正确的方式解决这个问题?我的解决方案:class ClearingJpaItemWriter<T> extends JpaItemWriter<T> { private EntityManagerFactory entityManagerFactory; @Override public void write(List<? extends T> items) { super.write(items); EntityManager entityManager = EntityManagerFactoryUtils.getTransactionalEntityManager(entityManagerFactory); if (entityManager == null) { throw new DataAccessResourceFailureException("Unable to obtain a transactional EntityManager"); } entityManager.clear(); } @Override public void setEntityManagerFactory(EntityManagerFactory entityManagerFactory) { super.setEntityManagerFactory(entityManagerFactory); this.entityManagerFactory = entityManagerFactory; } }您可以entityManager.clear();在 write 方法中看到添加的内容。作业配置:@Beanpublic JpaItemWriter postgresWriter() { JpaItemWriter writer = new ClearingJpaItemWriter(); writer.setEntityManagerFactory(pgEntityManagerFactory); return writer;}@Bean public Step appontmentInitStep(JpaItemWriter<Appointment> writer, FlatFileItemReader<Appointment> reader) { return stepBuilderFactory.get("initEclinicAppointments") .transactionManager(platformTransactionManager) .<Appointment, Appointment>chunk(5000) .reader(reader) .writer(writer) .faultTolerant() .skipLimit(1000) .skip(FlatFileParseException.class) .build(); }
1 回答
aluckdog
TA贡献1847条经验 获得超7个赞
这是一个有效的观点。( JpaItemWriter
and HibernateItemWriter
) 用于清除持久上下文,但已在BATCH-1635中删除(这是删除它的提交)。但是,这已被重新添加并HibernateItemWriter
在BATCH-1759中通过clearSession
参数(请参阅此提交)进行配置,但在JpaItemWriter
.
所以我建议打开一个针对 Spring Batch 的问题以添加相同的选项JpaItemWriter
,以便在写入项目后清除持久性上下文(这将与 一致HibernateItemWriter
)。
也就是说,要回答您的问题,您确实可以像以前一样使用自定义编写器来清除持久性上下文。
希望这可以帮助。
添加回答
举报
0/150
提交
取消