Po wywołaniu metody bez @Transactional
wewnątrz bloku transakcji transakcja nadrzędna będzie kontynuowana w nowej metodzie. Użyje tego samego połączenia z metody nadrzędnej (z @Transactional
) i każdego wyjątku spowodowanego w wywołanej metodzie (bez @Transactional
spowoduje wycofanie transakcji zgodnie z konfiguracją w definicji transakcji.
Jeśli wywołasz metodę z @Transactional
adnotacją z metody w @Transactional
ramach tego samego wystąpienia, wywoływane zachowanie transakcyjne metod nie będzie miało żadnego wpływu na transakcję. Ale jeśli wywołasz metodę z definicją transakcji z innej metody z definicją transakcji i znajdują się one w różnych instancjach, to kod w wywołanej metodzie będzie zgodny z definicjami transakcji podanymi w wywołanej metodzie.
Możesz znaleźć więcej informacji w sekcji Deklaratywny zarządzania transakcjami w dokumentacji transakcji wiosny .
Deklaratywny model transakcji Spring wykorzystuje proxy AOP. więc pełnomocnik AOP jest odpowiedzialny za tworzenie transakcji. Serwer proxy AOP będzie aktywny tylko wtedy, gdy metody z instancją są wywoływane spoza instancji.
will follow the transaction definitions given in the called method
. Ale jeśli wywołanie pochodzi z tej samej instancji obiektu, nie będzie miało żadnego efektu, ponieważ wywołanie nie będzie propagowane przez proxy aop, które są odpowiedzialne za obsługę transakcji.@Transactional
definicją z innego obiektu / instancji, to nawet jeśli metoda wywołująca ma inne@Transactional
atrybuty, wywołana metoda będzie postępować zgodnie z własną definicją transakcji.To zależy od poziomu propagacji . Oto wszystkie możliwe wartości poziomów .
Na przykład, jeśli poziom propagacji jest ZAGNIEŻDŻONY, bieżąca transakcja zostanie „zawieszona” i zostanie utworzona nowa transakcja ( uwaga: faktyczne utworzenie transakcji zagnieżdżonej będzie działać tylko na określonych menedżerach transakcji )
Domyślny poziom propagacji (to, co nazywasz „zachowaniem”) jest WYMAGANY . W przypadku wywołania metody „wewnętrznej”, która ma przypisaną do niej
@Transactional
adnotację (lub przeprowadzonej deklaratywnie za pomocą XML), zostanie ona wykonana w ramach tej samej transakcji , np. „Nic nowego” nie zostanie utworzone.źródło
@Transactional oznacza granicę transakcji (początek / koniec), ale sama transakcja jest powiązana z wątkiem. Po rozpoczęciu transakcji jest ona propagowana przez wywołania metod, aż pierwotna metoda powróci, a transakcja zostanie zatwierdzona / wycofana.
Jeśli wywoływana jest inna metoda, która ma adnotację @Transactional, propagacja zależy od atrybutu propagacji tej adnotacji.
źródło
Metoda wewnętrzna wpłynie na metodę zewnętrzną, jeśli metoda wewnętrzna nie ma adnotacji @Transactional.
W przypadku, gdy metoda wewnętrzna jest również opatrzona adnotacją @Transactional z
REQUIRES_NEW
, nastąpi następujące.... @Autowired private TestDAO testDAO; @Autowired private SomeBean someBean; @Override @Transactional(propagation=Propagation.REQUIRED) public void outerMethod(User user) { testDAO.insertUser(user); try{ someBean.innerMethod(); } catch(RuntimeException e){ // handle exception } } @Override @Transactional(propagation=Propagation.REQUIRES_NEW) public void innerMethod() { throw new RuntimeException("Rollback this transaction!"); }
Metoda wewnętrzna jest opatrzona adnotacją
REQUIRES_NEW
i zgłasza wyjątek RuntimeException, więc ustawi swoją transakcję na wycofanie, ale NIE WPŁYNIE na transakcję zewnętrzną. Transakcja zewnętrzna jest ZATRZYMYWANA, gdy rozpoczyna się transakcja wewnętrzna, a następnie WZNOWIONA PO zakończeniu transakcji wewnętrznej. Działają niezależnie od siebie, więc transakcja zewnętrzna MOŻE zostać pomyślnie zatwierdzona.źródło