Мое приложение загружает список объектов, которые необходимо обработать. Это происходит в классе, который использует планировщикДолжен ли я передать управляемый объект методу, требующему новой транзакции?
@Component
class TaskScheduler {
@Autowired
private TaskRepository taskRepository;
@Autowired
private HandlingService handlingService;
@Scheduled(fixedRate = 15000)
@Transactional
public void triggerTransactionStatusChangeHandling() {
taskRepository.findByStatus(Status.OPEN).stream()
.forEach(handlingService::handle);
}
}
В моих HandlingService
процессах каждой задачу в issolation использование REQUIRES_NEW
для уровня распространения.
@Component
class HandlingService {
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void handle(Task task) {
try {
processTask(task); // here the actual processing would take place
task.setStatus(Status.PROCCESED);
} catch (RuntimeException e) {
task.setStatus(Status.ERROR);
}
}
}
код работает только потому, что я начал родительскую сделку по TaskScheduler
класса. Если я удалю аннотацию @Transactional
, сущности больше не управляются, а обновление объекта задачи не распространяется на db.I не считаю естественным сделать транзакционный метод по расписанию.
Из того, что я вижу у меня есть два варианта:
1. Код Keep, как сегодня.
- Возможно, это просто я, и это правильный подход.
- Этот вариант имеет наименьшее количество поездок в базу данных.
2. Удалите @Transactional
аннотацию из планировщика, передать идентификатор задачи и перезагрузить сущность задачи в HandlingService.
@Component
class HandlingService {
@Autowired
private TaskRepository taskRepository;
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void handle(Long taskId) {
Task task = taskRepository.findOne(taskId);
try {
processTask(task); // here the actual processing would take place
task.setStatus(Status.PROCCESED);
} catch (RuntimeException e) {
task.setStatus(Status.ERROR);
}
}
}
- Имеет больше поездок в базу данных (один дополнительный запрос/элемент)
- Может быть выполнена с использованием
@Async
Можете ли вы предложить свое мнение, на котором это правильный путь решения таких проблем, может быть, с другим методом, о котором я не знал?
В этом примере синхронизируется ли сущность сущности сущности транзакции с сеансом внешней транзакции? Например, если объект «Задача» изменен внутри вложенной транзакции, это изменение применимо и к сеансу внешней транзакции? – froi
Следуйте моему вопросу, так как сеанс внешней транзакции покраснел, означает ли это, что изменения задачи будут считаться «устаревшими» изменениями? – froi