Oracle 调用长时间运行的findAll()存储库方法时,Spring计划任务停止运行
我有SpringBoot2应用程序和Spring数据。这是数据库连接定义:Oracle 调用长时间运行的findAll()存储库方法时,Spring计划任务停止运行,oracle,hibernate,spring-data,hikaricp,spring-scheduled,Oracle,Hibernate,Spring Data,Hikaricp,Spring Scheduled,我有SpringBoot2应用程序和Spring数据。这是数据库连接定义: spring.datasource.url=jdbc:oracle:thin:@XXX:9555:YYY spring.datasource.username=uname spring.datasource.password=pwd spring.datasource.hikari.connection-test-query=SELECT 1 FROM DUAL spring.datasource.hikari.min
spring.datasource.url=jdbc:oracle:thin:@XXX:9555:YYY
spring.datasource.username=uname
spring.datasource.password=pwd
spring.datasource.hikari.connection-test-query=SELECT 1 FROM DUAL
spring.datasource.hikari.minimum-idle=1
spring.datasource.hikari.maximum-pool-size=5
spring.datasource.hikari.pool-name=pool
然后我有一个cron计划作业,定义如下:
@Async
@Scheduled(cron = "${calculate.cron}")
public void calculate() {
try {
if (syncInstancesForTaskExecution()) {
calculatorService.calculate();
// Remove task start execution DT
instanceSyncService.setTaskLastExecutionDt(null);
}
} catch (Exception e) {
logger.error("Scheduled task failed", e);
}
这是CalculatorService中的计算方法:
public void calculateRequests() {
logger.trace("Task deleting old data");
calculatedRepository.deleteAll();
logger.trace("Task deleted old data");
logger.trace("Task selecting new data");
Iterable<ServiceRequestView> srv = viewRepository.findAll();
logger.trace("Task selected new data");
...
public void calculateRequests(){
logger.trace(“任务删除旧数据”);
calculatedRepository.deleteAll();
logger.trace(“任务删除旧数据”);
trace(“任务选择新数据”);
Iterable srv=viewRepository.findAll();
logger.trace(“任务选择的新数据”);
...
计划作业背后的逻辑是,它基本上每晚运行,从表中删除旧数据(calculatedRepository.deleteAll()
),从数据库视图中选择新数据(viewRepository.findAll()
),然后将新数据保存在表中
我遇到的问题是,有时执行在viewRepository.findAll()之后挂起
被调用。在数据库上,我们可以看到select被调用并执行。目前,在我看来,如果select的执行时间少于1小时,则一切正常,如果select的执行时间长于1小时,则问题出现
日志中没有任何错误,我唯一能看到的是,在调用findAll()
和下一个日志行(logger.trace(“任务选择的新数据”)
后,日志停止我还可以看到数据库上的更新没有执行,所以这不仅仅是因为日志记录不起作用,而且整个任务的执行似乎停止/结束了
你知道这可能会导致这个问题吗?数据源、Hikari池、计划作业还是什么?我找不到原因
编辑:
我已经按照建议更新了代码-实现了
从表中删除和插入到…
但问题仍然存在。插入到…
查询在1小时2分钟后执行,但没有在表中插入任何内容,日志看起来也一样:(您编写代码的方式。使用截断来代替删除,而不是检索所有内容然后存储所有内容。将选择…写入到查询中,这样做只需一次即可完成所有操作。速度会快得多,占用的内存会少很多。谢谢,我将以这种方式实现它。这将修复性能,但为什么o您认为这会导致代码挂起的问题吗?因为findAll
会将每个记录加载到内存中。因此,如果您有1000000行,hibernate需要获取所有行,请创建对象,然后将它们逐个插入(即使使用saveAll
),您可能没有使用批处理(即每次50或100)导致在单个事务中执行脏检查。确定。但在这种情况下,在调用saveAll()
之前,代码会挂起,这应该发生在日志logger.trace(“任务选择的新数据”)之后
已打印。而日志从未打印,它挂在该行之前。我已实现了从表中删除和插入到…
中,但它仍然不工作。插入到…
查询在1小时2分钟后执行,但表中没有插入任何内容,日志看起来也一样。:(