我在工作中进行了分区,这是从数据库中读取数据并生成文件。例如,基于报告数量初始化分区映射器。它设置了100个分区和5个线程。它会使用100个不同的查询来生成100个文件。如果所有查询都运行良好,则说明作业运行成功。但是,当读取器由于查询超时而失败时,它会关闭并关闭写入器和读取器的连接,但不会停止并立即对批处理元数据表进行更新。而是线程挂了一段时间,并更新到批处理元数据表。并且它影响后续线程。
有趣的是,第一个线程故障的工作与上述timout(15min)完全相同。当下一个线程失败时,它将花费更多的时间,例如15 + 15 = 30mins。随后,它累加了上一个线程的时间并结束了长时间运行的工作。
仅当线程由于某种原因而开始失败(在我的情况下,是查询超时)时才会发生。出现故障时,线程似乎无法正确清理资源。并且它使线程存活很长时间。 Reader打开连接和结果集。关闭连接和结果集的close方法。
In Reader open()
con = dataSource.getConnection();
resultSet=null;
preparedStatement = con.prepareStatement(sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY,
ResultSet.HOLD_CURSORS_OVER_COMMIT);
try {
resultSet = preparedStatement.executeQuery();
} catch (Exception e) {
e.printStackTrace();
}
Reader close()
if(!resultSet.isClosed()) {
resultSet.close();
}
preparedStatement.close();
con.close();
Partition class;
partitionPlan.setThreads(getThreadCount());
partitionPlan.setPartitions(numberOfPartitions); //numberOfPartitions count comes from another dao.
for (int idx = 0; idx < numberOfPartitions; idx++) {
Properties threadProperties = new Properties();
threadProperties.setProperty("threadNumber", idx + "");
threadProperties.setProperty("sqlId", dynSqlId); //each thread will be set with some sql query.
props[idx] = threadProperties;
}
partitionPlan.setPartitionProperties(props);
return partitionPlan;
预期结果,线程应在失败后立即更新批处理元数据表。并且应该清理。当线程故障增加时,线程挂起时间也会增加。