spring-batch - Spring Batch:我们如何从数据库中预加载值并将其用于处理器部分
问题描述
我有一个要求,我需要在 ItemProcessor 部分查找几个表。我不想对 ItemProcessor 部分中的每一行进行多次 JDBC 调用,当 Spring Batch 开始处理更多记录时,这可能会导致性能问题。避免这种情况的解决方法是什么?有没有办法在 ItemProcessor 或批处理开始之前预加载这些对象,并可以在 ItemProcessor 中引用它?
解决方案
您可以在 Spring 应用程序上下文初始化期间使用 @PostConstruct 注释您的方法来读取数据。使您的 ItemReader 的读取方法从列表中返回值。当整个列表完成时返回 null。这将停止阅读。
@Service
public class YourItemReader implements ItemReader<DomainObject> {
private int index;
List<DomainObject> dbRows;
@PostConstruct
public void init() {
List<DomainObject> //read from database
}
@Override
public DomainObject read(){
if (null != dbRows && index < dbRows.size()) {
return dbRows.get(index);
}
return null;
}
如果记录数以百万计,我建议从您的数据库中进行基于块的读取,而不是一次读取所有记录,这可能会导致垃圾收集器内存不足异常。这可以通过在表中添加一个名为 STATUS 的列来轻松完成,以跟踪已处理记录的状态。最初,当您将数据加载到表中时,将状态设置为“未处理”,当您的 ItemReader 读取记录块时,将状态设置为“进行中”。一旦您的 ItemProcessor 或 ItemWriter 完成其处理,将状态从“IN PROGRESS”更改为“PROCESSED”。确保将从数据库中获取数据的方法设置为“同步”。这将确保多个线程不会从数据库中获取相同的数据。
public List<DomainObject> read(){
return fetchDataFromDb();
}
private synchronized List<DomainObject> fetchProductAssociationData(){
//read your chunk-size of records from database which has status as 'NOT
PROCESSED'
and change the status of the data which is read to 'IN PROGRESS'
return list;
}
推荐阅读
- node.js - 我在尝试运行 serve -s build 时收到错误消息
- python - Python 网络钩子 API
- r - How to link 2 widget options dynamically in R Shiny?
- javascript - 应该用间隔替换多少超时?
- sql - SQL 中有没有一种方法可以更改地理列中的经纬度值倒置的值?
- reactjs - 将全栈应用程序部署到 Heroku 时如何解决 Eslint 错误?
- typescript - 如何声明 boolean 或 () => boolean 类型的属性
- python-3.x - wxPython 对象没有属性
- laravel - 如何在 Laravel 的三元运算符中使用 HREF
- c# - asp net core如何使用公共交通将数据从http get请求发布到Rabbit MQ?