2012-10-24 22 views
30

Mam metodę, która ma właściwość transakcyjnej na propagation = Propagation.REQUIRES_NEW:Wiosna transakcja WYMAGANE vs REQUIRES_NEW: Wycofywanie transakcji

@Transactional(propagation = Propagation.REQUIRES_NEW) 
public void createUser(final UserBean userBean) { 
    //Some logic here that requires modification in DB 
} 

Metoda ta może być wywołana wielokrotnie jednocześnie, a dla każdej transakcji w przypadku wystąpienia błędu niż jest wycofywany (niezależnie od innych transakcji).

Problem polega na tym, że może to zmusić Spring do utworzenia wielu transakcji, nawet jeśli inna jest dostępna, i może powodować pewne problemy z wydajnością.


doc Java propagation = Propagation.REQUIRED mówi: Support a current transaction, create a new one if none exists.

To wydaje się rozwiązać problem z wydajnością, prawda?

Co z problemem wycofania? Co się stanie, jeśli nowe wywołanie metody zostanie wycofane podczas używania istniejącej transakcji? czy to nie spowoduje wycofania całej transakcji nawet z poprzednich rozmów?

[EDIT] Chyba moje pytanie nie było wystarczająco jasne:

Mamy setki klientów podłączonych do naszego serwera.

Dla każdego klienta musimy oczywiście wysłać opinię o transakcji (OK lub wyjątek -> wycofanie).

Moje pytanie brzmi: czy używam REQUIRED, czy oznacza to, że używana jest tylko jedna transakcja, a jeśli 100. klient napotka problem, transakcja 1. klienta również zostanie wycofana?

+1

to właśnie kwestia REQUIRES_NEW, do tworzenia nowych transakcji za każdym razem, gdy metoda jest wywoływana. I tak, jeśli masz WYMAGANE i transakcja zostanie wycofana, wycofa całą sprawę. –

+0

@DenisTulskiy Cała sprawa polegająca na tym, że każde poprzednie połączenie z tą fonction lub bieżącym stosem połączeń? –

+2

@jidma: cała transakcja, patrz odpowiedź @ Eugena, jeśli 'createUser' jest pierwszą metodą, którą wywołuje twój kod klienta, to REQUIRES_NEW i REQUIRED to to samo –

Odpowiedz

48

Używanie REQUIRES_NEW ma znaczenie tylko wtedy, gdy metoda jest wywoływana z kontekstu transakcyjnego; gdy metoda zostanie wywołana z kontekstu nietransakcyjnego, zachowa się dokładnie tak jak REQUIRED - utworzy nową transakcję.

Nie oznacza to, że będzie tylko jedna pojedyncza transakcja dla wszystkich klientów - każdy klient zacznie od kontekstu nietransakcyjnego, a gdy tylko przetwarzanie żądania uderzy w @Transactional, utworzy nowe transakcja.

Tak więc mając na uwadze, że użycie REQUIRES_NEW ma sens dla semantyki tej operacji - niż nie martwiłbym się o wydajność - to podręcznikowa przedwczesna optymalizacja - wolałbym podkreślić poprawność i integralność danych oraz martwić się wydajnością po zebraniu danych o wydajności, a nie wcześniej.

Po wycofaniu - użycie REQUIRES_NEW wymusi rozpoczęcie nowej transakcji, więc wyjątek spowoduje wycofanie tej transakcji. Jeśli istnieje również inna transakcja, która również była wykonywana - która zostanie lub nie zostanie wycofana, w zależności od tego, czy wyjątek powoduje wypalenie stosu, czy zostanie przechwycony - Twój wybór, w zależności od specyfiki operacji. Ponadto, aby uzyskać bardziej szczegółową dyskusję na temat strategii transakcyjnych i wycofywania zmian, polecam: «Transaction strategies: Understanding transaction pitfalls», Mark Richards.

+0

Czy możesz spojrzeć na to pytanie https://stackoverflow.com/questions/44539861/spring-transactional-commit-failures-deby-eclipselink? Czy potrzebuję 'REQUIRES_NEW', odpowiedź zwrócona po pesist zrobić później jakiś czas został wycofany. – vels4j

10

Jeśli naprawdę musisz to zrobić w oddzielnej transakcji, musisz użyć REQUIRES_NEW i żyć z obciążeniem wydajności. Uważaj na martwe zamki.

wolałbym zrobić to w inny sposób:

  • Zweryfikuj dane na stronie Java.
  • Uruchom wszystko w ramach jednej transakcji.
  • Jeśli coś pójdzie nie tak po stronie DB -> jest to poważny błąd DB lub projekt sprawdzania poprawności. Przywróć wszystko i rzuć krytyczny błąd na najwyższym poziomie.
  • Napisz dobre testy jednostkowe.
+0

Mamy setki klientów połączonych z naszym serwerem. Dla każdego klienta musimy przesłać opinię o transakcji (OK lub wyjątek -> wycofanie). Pozostaje mi pytanie: czy używam opcji "WYMAGANE", czy oznacza to, że używana jest tylko jedna transakcja, a jeśli 100. klient napotka problem, transakcja pierwszego klienta zostanie wycofana? –

Powiązane problemy