No transaction aspect-managed TransactionStatus in scope] Przy asynchronicznych metodach w spring MVC

Odpowiedz Nowy wątek
2018-12-15 00:00
0

Chciałbym mieć współbieżny web serwis tak żeby w momencie kiedy jeden kontroller obsługuje mi jedną część web serwisu, to wtedy w drugiej karcie przeglądarki mógłbym otworzyć sobie zupełnie inną a co gorsza żeby to była tranzakcja xD . Użycie @Async raczej nie wchodzi w gre bo wtedy to i tak asynchroniczne byłyby metody warstwy serwisu ale nie całego kontrollera czyli gdybym miał w jednej karcie np. generowanie formularza(tak generowałoby się szybciej(wiem że nie zawze) bo asynchronicznie)to druga otworzona później musiałaby czekać w kolejce a nie o to mi chodzi
Więc chciałem użyć Callable ale gdy próbuję zrobić to w formie tranzakcji to wyskakuje mi błąd

There was an unexpected error (type=Internal Server Error, status=500).
No transaction aspect-managed TransactionStatus in scope
org.springframework.transaction.NoTransactionException: No transaction aspect-managed TransactionStatus in scope at org.springframework.transaction.interceptor.TransactionAspectSupport.currentTransactionStatus(TransactionAspectSupport.java:124) at org.springframework.samples.petclinic.controller.VisitController$1.call(VisitController.java:127) at org.springframework.samples.petclinic.controller.VisitController$1.call(VisitController.java:113) at org.springframework.web.context.request.async.WebAsyncManager.lambda$startCallableProcessing$4(WebAsyncManager.java:323) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748)

Jak mógłbym zrobić tę część żeby była w zakresie tranzakcji?

  @Transactional(isolation = Isolation.READ_COMMITTED)
    @PostMapping("/owners/{ownerId}/pets/{petId}/visits/{visitId}/edit")
    public Callable<String> processUpdateForm(@PathVariable("visitId") int visitId, @Valid Visit visit, BindingResult result){

        return new Callable<String>() {
            @Transactional(isolation = Isolation.READ_COMMITTED)
            public String call() throws Exception {
                visit.setId(visitId);
                if (result.hasErrors()) {

                    return "pets/createOrUpdateVisitForm";
                } else {

                    visitService.update(visit);

                    System.out.println("po dodaniu");
                    System.out.println(visitService.findById(visitId).getPrice());
                    System.out.println("po dodani2");
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                    return "redirect:/owners/{ownerId}";
                }

            }
        };

Pozostało 580 znaków

2018-12-15 00:32
0

Niestety widac że nie wiesz jak transakcje w Springu działają. Spring używa ThreadLocali, tak więc jeśli jest stworzony nowy wątek dla nowego requestu to wszystkie transakcje muszą się wykonywać w tyższe wątku. W ogóle nie rozumiesz co robisz niestety, polecam nauczyć się co to jest programowanie aspektowe i jak działają kontenery IoC...
Zresztą ogólnie ten twój cały zamysł jest bardzo dziwny :D :D :D


Nie pomagam przez PM. Pytania zadaje się na forum.
edytowany 1x, ostatnio: scibi92, 2018-12-15 00:36
Pokaż pozostałe 6 komentarzy
Wiem że to nic złego nie wiedzieć ale ty nie dość że w zasadzie nic nie pomogłeś to po mnie jeździsz - masterkwi 2018-12-15 00:50
No to musisz chyba zaimplementować dwustronną komunikację, żeby serwer mógł wiedzieć, ile i jakich zakładek masz wciąż otwartych. Ale prościej chyba byłoby doczytać jak to działa. No chyba, że Twój temat jednak ma sens i serwery hostujące Springa są jednowątkowe, ale w to to nawet ja nie uwierzę. - somekind 2018-12-15 00:53
Chciałem żeby pokazać jak wpływają rózne poziomy dostępu jak np.READ_COMMITTED i READ_UNCOMMITTED i w trakcie wczytywania jednej karty chciałem debuggerem zastopować w trakcie jednej transakcji i odpalić sobie inną żeby zmienione dane przeczytała bo ta druga transakcja(T2) miałaby poziom dostępu ustawiony na właśnie READ_UNCOMMITED. Bez jakichś ustawień to było tak że napierw kończyła się tranzakcja T1 a potem zaczynała T2 mimo że w trakcie wykonywania T1 odpalałem T2UNCOMMITED) i czytała te zmienione dane, ale ona uruchamiała się po, więc trzeba było to zrobić równolegle - masterkwi 2018-12-15 01:02
To może się przenieś do postów z sensownymi informacjami w temacie. :) - somekind 2018-12-15 01:07
Nie no @somekind napisał prawdę odnośnie serwera i przeglądarki - scibi92 2018-12-15 01:08

Pozostało 580 znaków

2018-12-15 01:13
1

@masterkwi - problemem jest to, że chcesz użyć debugera, który pauzuje wykonywanie jakiegokolwiek kodu aplikacji, stąd efekt "kolejkowania" przetwarzania żądań. Bo w realnej aplikacji, to żądania przecież pójdą "równolegle" (w sensie na innych wątkach).


"HUMAN BEINGS MAKE LIFE SO INTERESTING. DO YOU KNOW, THAT IN A UNIVERSE SO FULL OF WONDERS, THEY HAVE MANAGED TO INVENT BOREDOM."

Pozostało 580 znaków

2018-12-15 04:24
1

@masterkwi: nic z tego co napisałeś w 1 poście nie ma sensu. Żadnego. Tomcat/jetty przecież są wielowątkowe, więc twoje osobne karty w przeglądarce są zupełnie niezależne od siebie. Zwracanie jakiegoś callable z kontrolera to pomysł tak dziwny i głupi że trudno mi się do niego odnieść. A co do transactional to zupełnie nie rozumiem co chcesz osiągnąć.


Masz problem? Pisz na forum, nie do mnie. Nie masz problemów? Kup komputer...

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0