Фрагмент фиктивного кода постановки задачи:Метод планировщика
@Scheduled(fixedRate = 30000)
@Transactional(readOnly = true)
public void scheduledTask() {
TaskExecutor threadPool = ctx.getBean(TaskExecutor.class);
long totalCount = someDao.someOperation("argument");
Runner runner;
for (int offset = 0; offset < totalCount; offset += 50) {
runner = ctx.getBean(Runner.class);
runner.setOffset(offset);
threadPool.execute(runner);
}
}
Runnable Implimentaion
@Component
@Scope(scopeName="prototype", proxyMode=ScopedProxyMode.TARGET_CLASS)
@Transactional
public class Runner implements Runnable {
private Integer offset;
private Integer limit;
private ISomeDao someDao;
public Runner(ISomeDao someDao) {
this.someDao = someDao;
}
public void setOffset(int offset) {
this.offset = offset;
this.limit = this.offset + 50;
}
@Override
public void run() {
List<Operation> operations = someDao.fetchData(offset, limit, someCriteria);
///
/// other business logic
}
}
Проблема, с которой я столкнулся:
В scheduleTask, программа правильно установила значение смещения (проверка в режиме отладки), но он недоступен в методе run класса Runner, смещение всегда равно null.Когда я удаляю пружинную аннотацию из класса Runner и создаю ее вручную в scheduleTask, тогда я могу получить доступ к значению смещения, но он выдаст исключение, так как нет доступного менеджера транзакций, который ожидается.
Я также попытался внедритьEntityManger в
runner = ctx.getBean(Runner.class, ctx.getBean(EntityManager.class);
в запланированной задаче, когда я удаляю аннотацию Spring, но проблема остается той же, так как поток не управляется Spring
Я потратил час на поиск решения.