为什么我的预定作业没有并行执行
Why my scheduled jobs are not executed parallelly
我想弄清楚为什么我的计划作业没有并行执行。也许我的交易管理有问题?方法 JobScheduledExecutionService.execute()
是 @Scheduled
和 fixedRate=250
,因此无论上一个作业是否完成,它都应该每 250 毫秒触发一次。由于日志原因,它没有按预期工作。
日志:https://pastebin.com/M6FaXpeE
我的代码如下。
@Service
@Slf4j
public class JobExecutionService {
private final TransactionalJobExecutionService transactionalJobExecutionService;
@Autowired
public JobExecutionService(TransactionalJobExecutionService transactionalJobExecutionService) {
this.transactionalJobExecutionService = transactionalJobExecutionService;
}
public void execute() {
TestJob job = transactionalJobExecutionService.getJob();
executeJob(job);
transactionalJobExecutionService.finishJob(job);
}
private void executeJob(TestJob testJob) {
log.debug("Execution-0: {}", testJob.toString());
Random random = new Random();
try {
Thread.sleep(random.nextInt(3000) + 200);
} catch (InterruptedException e) {
log.error("Error", e);
}
log.debug("Execution-1: {}", testJob.toString());
}
}
@Service
@Slf4j
public class JobScheduledExecutionService {
private final JobExecutionService jobExecutionService;
@Autowired
public JobScheduledExecutionService(JobExecutionService jobExecutionService) {
this.jobExecutionService = jobExecutionService;
}
@Scheduled(fixedRate = 250)
public void execute() {
log.trace("Job fired");
jobExecutionService.execute();
}
}
@Service
@Slf4j
@Transactional
public class TransactionalJobExecutionService {
private final Environment environment;
private final TestJobRepository testJobRepository;
private final TestJobResultRepository testJobResultRepository;
@Autowired
public TransactionalJobExecutionService(Environment environment, TestJobRepository testJobRepository, TestJobResultRepository testJobResultRepository) {
this.environment = environment;
this.testJobRepository = testJobRepository;
this.testJobResultRepository = testJobResultRepository;
}
public TestJob getJob() {
TestJob testJob = testJobRepository.findFirstByStatusOrderByIdAsc(
0
);
testJob.setStatus(1);
testJobRepository.save(testJob);
return testJob;
}
public void finishJob(TestJob testJob) {
testJobResultRepository.save(
new TestJobResult(
null,
testJob.getId(),
environment.getProperty("local.server.port")
)
);
}
}
@Configuration
public class SchedulingConfigurerConfiguration implements SchedulingConfigurer {
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
taskScheduler.setPoolSize(32);
taskScheduler.initialize();
taskRegistrar.setTaskScheduler(taskScheduler);
}
}
原因是调度程序将仅触发一个事件,该事件将由一个线程执行,然后我没有看到您在逻辑中生成多个线程以进行并行执行。 jobExecutionService.execute(); 的调用在 JobScheduledExecutionService 的 execute() 中是在那个线程中。所以总的来说它最终是顺序执行的。
似乎您需要在 JobExecutionService 中放置多线程 [基于可调用未来] 逻辑:execute() 以选择作业 [transactionalJobExecutionService.getJob()] 并在其中调用 executeJob() 。希望这有帮助..
我想弄清楚为什么我的计划作业没有并行执行。也许我的交易管理有问题?方法 JobScheduledExecutionService.execute()
是 @Scheduled
和 fixedRate=250
,因此无论上一个作业是否完成,它都应该每 250 毫秒触发一次。由于日志原因,它没有按预期工作。
日志:https://pastebin.com/M6FaXpeE
我的代码如下。
@Service
@Slf4j
public class JobExecutionService {
private final TransactionalJobExecutionService transactionalJobExecutionService;
@Autowired
public JobExecutionService(TransactionalJobExecutionService transactionalJobExecutionService) {
this.transactionalJobExecutionService = transactionalJobExecutionService;
}
public void execute() {
TestJob job = transactionalJobExecutionService.getJob();
executeJob(job);
transactionalJobExecutionService.finishJob(job);
}
private void executeJob(TestJob testJob) {
log.debug("Execution-0: {}", testJob.toString());
Random random = new Random();
try {
Thread.sleep(random.nextInt(3000) + 200);
} catch (InterruptedException e) {
log.error("Error", e);
}
log.debug("Execution-1: {}", testJob.toString());
}
}
@Service
@Slf4j
public class JobScheduledExecutionService {
private final JobExecutionService jobExecutionService;
@Autowired
public JobScheduledExecutionService(JobExecutionService jobExecutionService) {
this.jobExecutionService = jobExecutionService;
}
@Scheduled(fixedRate = 250)
public void execute() {
log.trace("Job fired");
jobExecutionService.execute();
}
}
@Service
@Slf4j
@Transactional
public class TransactionalJobExecutionService {
private final Environment environment;
private final TestJobRepository testJobRepository;
private final TestJobResultRepository testJobResultRepository;
@Autowired
public TransactionalJobExecutionService(Environment environment, TestJobRepository testJobRepository, TestJobResultRepository testJobResultRepository) {
this.environment = environment;
this.testJobRepository = testJobRepository;
this.testJobResultRepository = testJobResultRepository;
}
public TestJob getJob() {
TestJob testJob = testJobRepository.findFirstByStatusOrderByIdAsc(
0
);
testJob.setStatus(1);
testJobRepository.save(testJob);
return testJob;
}
public void finishJob(TestJob testJob) {
testJobResultRepository.save(
new TestJobResult(
null,
testJob.getId(),
environment.getProperty("local.server.port")
)
);
}
}
@Configuration
public class SchedulingConfigurerConfiguration implements SchedulingConfigurer {
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
taskScheduler.setPoolSize(32);
taskScheduler.initialize();
taskRegistrar.setTaskScheduler(taskScheduler);
}
}
原因是调度程序将仅触发一个事件,该事件将由一个线程执行,然后我没有看到您在逻辑中生成多个线程以进行并行执行。 jobExecutionService.execute(); 的调用在 JobScheduledExecutionService 的 execute() 中是在那个线程中。所以总的来说它最终是顺序执行的。
似乎您需要在 JobExecutionService 中放置多线程 [基于可调用未来] 逻辑:execute() 以选择作业 [transactionalJobExecutionService.getJob()] 并在其中调用 executeJob() 。希望这有帮助..