Czy istnieje proste rozwiązanie do zapisywania danych w bazie danych przy użyciu WZP w nowym wątku?Wywoływanie metod @Transactional z innego wątku (Runnable)
Aplikacja internetowa oparta na mojej wiosce pozwala użytkownikowi zarządzać zaplanowanymi zadaniami. W czasie wykonywania może tworzyć i uruchamiać nowe instancje predefiniowanych zadań. Używam Spring TaskScheduler i wszystko działa dobrze.
Ale muszę zapisać wynik boolean każdego wypalonego zadania do bazy danych. Jak mogę to zrobić?
EDYTOWANIE: Muszę uogólnić moje pytanie: muszę wywołać metodę na mojej klasie @Service z zadań. Ponieważ wynik zadania musi zostać "przetworzony" przed zapisaniem w bazie danych.
EDIT 2: Uproszczona wersja mojego problematycznego kodu przychodzi tutaj. Kiedy funkcja saveTaskResult() jest wywoływana z programu planującego, komunikat jest drukowany, ale nic nie jest zapisywane w db. Ale za każdym razem, gdy wywoływam saveTaskResult() ze sterownika, rekord jest poprawnie zapisywany w bazie danych.
@Service
public class DemoService {
@Autowired
private TaskResultDao taskResultDao;
@Autowired
private TaskScheduler scheduler;
public void scheduleNewTask() {
scheduler.scheduleWithFixedDelay(new Runnable() {
public void run() {
// do some action here
saveTaskResult(new TaskResult("result"));
}
}, 1000L);
}
@Transactional
public void saveTaskResult(TaskResult result) {
System.out.println("saving task result");
taskResultDao.persist(result);
}
}
Jaki jest dokładnie problem? Zaczynasz wątek, nazywasz swoje usługi wiosenne dokładnie tak, jak zrobiłbyś, gdybyś nie rozpoczął wątku, i wszystko powinno być w porządku. –
Problemem jest metoda biznesowa celu @Transactional. Kiedy wywołasz tę metodę w run(), dane nie zostaną utracone. (Mam zaktualizowany tytuł pytania) –
Przechwytywacz transakcyjny nie dba o to, czy wątek wywołujący metodę jest wątkiem utworzonym przez twój kontener serwletu, czy wątkiem utworzonym przez ciebie. Powinno działać. Pokaż nam jakiś kod. –