我尝试在微服务中提取超过100万条记录。我遇到错误。我需要不断增加服务的应用内存,以便提取大量数据。有没有什么方法可以用来提取大量数据,而不是增加应用内存。
[错误]资源耗尽事件:JVM无法从堆中分配内存。2022- 1/0 - 11 T11:22:04. 898 +08:00 [APP/PROC/WEB/0] [ERR]资源已耗尽!(1/0)
@Value("${batch-size}")
private int batchSize;
public void archiveTableRecords(JdbcTemplate sourceDbTemplate, JdbcTemplate targetDbTemplate,
ArchiveConfigDTO archiveObj) {
try {
String sourceTable = archiveObj.getSourceTable();
String archive_months =archiveObj.getArchiveCriteriaMonths();
List<Object> primaryKeyValueList = new ArrayList<>();
String compareDate1 = getCSTDateNew(archive_months);
logger.info("Archive criteria date: {}", compareDate1);
List<Map<String, Object>> sourceRecords = sourceDbTemplate
.queryForList(ArchiveSQLQueries.buildSQLQueryToFetchSourceRecords(sourceTable), compareDate1);
int sourceRecordsSize = sourceRecords.size();
logger.info("Fetched {} {} record(s)", sourceRecords.size(), sourceTable);
if (sourceRecordsSize > 0) {
int recordsInserted = copySourceRecords(targetDbTemplate, archiveObj.getTargetTable(),
archiveObj.getPrimaryKeyColumn(), sourceRecords, primaryKeyValueList);
if (recordsInserted > 0)
deleteSourceRecords(sourceDbTemplate, sourceTable, archiveObj.getPrimaryKeyColumn(),
primaryKeyValueList);
}
} catch (Exception e) {
logger.error("Exception in archiveTableRecords: {} {}", e.getMessage(), e);
}
}
public static String buildSQLQueryToFetchSourceRecords(String sourceTable) {
StringBuilder sb = new StringBuilder("SELECT * FROM " + sourceTable + " where update_dts <= ?");
return sb.toString();
}
public int copySourceRecords(JdbcTemplate targetDbTemplate, String targetTable, String primaryKeyColumn,
List<Map<String, Object>> sourceRecords, List<Object> primaryKeyValueList) {
int result = 0;
logger.info("Copying records to {}", targetTable);
int[][] insertResult = targetDbTemplate.batchUpdate(
ArchiveSQLQueries.buildSQLTargetRecordInsertionQuery(targetTable, sourceRecords.get(0),
primaryKeyColumn),
sourceRecords, batchSize, new ParameterizedPreparedStatementSetter<Map<String, Object>>() {
@Override
public void setValues(PreparedStatement ps, Map<String, Object> argument) throws SQLException {
int index = 1;
for (Entry<String, Object> obj : argument.entrySet()) {
if (obj.getKey().equals(primaryKeyColumn))
primaryKeyValueList.add(obj.getValue());
else
ps.setObject(index++, obj.getValue());
}
}
});
result = getSumOfArray(insertResult);
logger.info("Inserted {} record(s) in {}", result, targetTable);
return result;
}
I have tried above code when fetching the data somehow i’m getting error .
1条答案
按热度按时间vohkndzv1#
根据方法名称判断,您可以从一个表复制到另一个表。使用
LIMIT
和OFFSET
分批执行此操作。简化示例:对于下一批,使用已处理记录的数量更改偏移量。更多示例请参考documentation。
ORDER BY
一列,这样您可以先获取最旧的数据,最新的数据在最后,以确保不会获取重复的数据。如果主键是自动递增的id,则这是实现此目的的好选择。如果您需要计数用于记录目的,请使用
COUNT
函数,或使用批次计数计算已行程实体的数目。