Moja aplikacja ładuje listę elementów, które powinny zostać przetworzone. Dzieje się to w klasie, która wykorzystuje harmonogramCzy powinienem przekazać zarządzany podmiot do metody wymagającej nowej transakcji?
@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);
}
}
W moich HandlingService
procesów każde zadanie w issolation użyciu REQUIRES_NEW
na poziomie propagacji.
@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);
}
}
}
Kod działa tylko dlatego zacząłem transakcji nadrzędnej na TaskScheduler
klasie. Po usunięciu adnotacji @Transactional
obiekty nie są już zarządzane, a aktualizacja encji zadania nie jest propagowana do bazy danych. Nie wydaje mi się naturalne, aby zaplanowana metoda była transakcyjna.
Z tego co widzę, mam dwie opcje:
1. Kod Przechowywać jak to jest dzisiaj.
- Może `s tylko ja i to jest prawidłowa aproach.
- Ten wariant ma najmniejszą liczbę odwiedzin w bazie danych.
2. Wyjąć @Transactional
adnotacji z terminarza, przechodzą identyfikator zadania i przeładować podmiot zadania w 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);
}
}
}
- ma więcej wyjazdów do bazy danych (jeden dodatkowy zapytań/element)
- mogą być wykonywane przy użyciu
@Async
Czy możesz zaoferować swoją opinię na temat, który jest poprawny sposób radzenia sobie z tego rodzaju problemami, być może z inną metodą, o której nie wiedziałem?
Czy w tym przykładzie pamięć podręczna sesji zagnieżdżonej transakcji zostanie zsynchronizowana z sesją zewnętrznej transakcji? Na przykład, jeśli jednostka "Zadanie" zostanie zmieniona w zagnieżdżonej transakcji, czy ta zmiana będzie obowiązywać również w sesji transakcji? – froi
Po udzieleniu odpowiedzi na moje pytanie, gdy sesja transakcji zewnętrznej zostanie przepłukana, czy oznacza to, że zmiany w Zadań będą liczone jako "nieaktualne" zmiany? – froi