Pytanie o transakcje

0

Mam kilka pytań o transakcje.

  1. W jakich przypadkach właściwie należy je używać ? Czy są jakieś dobre praktyki ich użycia ?
  2. Co konkretnie znaczy stosowanie readOnly = true w atrybucie tej adnotacji i kiedy się powinno tego używać ?
  3. Czy stosowanie adnotacji @Transactional oraz @Cacheable działa jeśli stosujemy je na metodzie z dostępnością package scope ? Wiem, że musimy te metody wywołać z zewnątrz klasy z racji dynamic proxy, ale nie wiem jak to działa z dostępnością package scope zamiast public ?

Pozdrawiam

0

To może inaczej .. czy aby uzyć transakcje na metodzie wystarczy, że po prostu mamy kilka zapytań do bazy czy są jakieś inne przyczyny jej użycia ?

0

Transakcje mają otaczać operacje które powinny być "atomowe" ze względu na spójność danych w aplikacji. Np. wyobraź sobie że piszesz system bankowy i implementujesz przelewy. Chcesz zabrać z jednego konta i dodać na drugie konto. A co jeśli się coś "wywali" w międzyczasie? Zabrałeś z konta X i nie dodałeś na konto Y, co wtedy? Widać ze taka operacja powinna być atomowa, ma się wykonać albo w całości albo wcale.

0

Ok, a czy dobrą praktyką jest nakładanie na serwis aplikacyjny(taki z DDD - orkiestrujący wywołania jakiejś logiki czy zapisania w bazie) takiej adnotacji, aby wszystkie jej metody publiczne były transakcyjne ? Albo inaczej - czy nałożenie takiej adnotacji na metodę takiego serwisu może być w jakimś przypadku użytka nieprawidłowo (nie powinno jej być) ?

0

Jeśli taka metoda wykonuje tylko jedno query to transakcja nie ma w ogóle żadnego sensu.

0

Query mówisz w sensie takiego które coś zmienia w bazie ? Bo chyba nie ma sensu nakładać transakcje na metody, które tylko coś pobierają ?

I czy jeśli mamy transkację to w ogóle należy stosować metody save lub saveFlush ?

0

Czasami jest. Jeśli masz operacje które wymagają kilku insertów/update'ów żeby zachować spójność danych, to nie chciałbyś żeby w międzyczasie ktoś zrobił selecta i wyciągnął niespójne dane.

0

Bo chyba nie ma sensu nakładać transakcje na metody, które tylko coś pobierają ?

Ryzykowne założenie ;) Transakcje wprowadzają pewien porządek operacji i masz pewność co do spójności danych które czytasz. Wynik selecta odpalonego w transakcji która wystartowała później niż tansakcja X pojawi się dopiero kiedy X się zakończy (w taki czy inny sposób). W innym wypadku mozesz mieć jakieś dirty ready.

0

Chwilka, bo chyba nie do końca zrozumiałem.

  1. Jeśli mamy kilka insertów/updatów w metodzie to wymaga ona transakcji
  2. Jeśli mam 1 insert/update to nie ma takiego sensu
  3. Jeśli mamy samo query w metodzie to też dajemy transakcje czy mówisz o innym przypadku?

No i co z tym save i saveAndFlush w metodzie transakcyjnej ? Używać czy nie skoro jest dirty checking ?

@Shalom
Czyli jeśli użytkownik da selecta w transkacji, w której dane są przetwarzane jeszcze w innej transakcji to wystąpi pewne opóźnienie tak ?

W takim razie jest jakaś zasada mówiąca kiedy na metody typu query, czyli selecty dawać transakcje ?

0
  1. Tak
  2. Wydaje mi się ze większość baz danych robi auto-transakcje na query w takiej sytuacji
  3. jw, ale warto to zweryfikować!

Czyli jeśli użytkownik da selecta w transkacji, w której dane są przetwarzane jeszcze w innej transakcji to wystąpi pewne opóźnienie tak ?

Można się tego spodziewać.

0

@Shalom:
Dzięki.

A jak jest wtedy z tym użyciem metod savujących, o których wspomniałem ? Bo jeśli nie mamy transakcji no to trzeba save robić - nie ma wyjścia. A podczas transakcji ?

No i nałożenie transakcji może być błędem w jakimś wypadku ?

0
  1. Koniec transakcji automatycznie zrobi commit/flush. Save musisz zrobić zawsze. No chyba ze masz tam JPA i encje dołączone do kontekstu, ale nie polecam na tym polegać, więcej z tym problemów niż pożytku.
  2. Może być, bo możesz zrobić sobie jakis deadlock albo poważnie uwalić wydajność jak pozakładasz transakcje na długie operacje. Wyobraź sobie że pobierasz dane z jakiegoś RESTa a potem ładujesz do bazy i dasz transakcje na calą taką operacje...
0

No właśnie mówię o JPA, że tam działa dirty checking. Nie spotkałem się z innym przypadkiem użycia transakcji.

A spotkałem się jeszcze z takim case'em, gdzie baza była tak przeciążona, że przy zapisie do bazy hibernate dostał info, że encja została zapisana, miała przydzielone nowe id, a fizycznie jej w bazie jeszcze nie było. Pojawiły się, przez to problemy.

Rozwiązaniem było użycie Persistence Context zamiast Spring Daty i zrobienie metody refresh.

Zastanawiam się czy jest to do ogarnięcia jakoś spring datą. Myślałem o tym, żeby przez zwróceniem odpowiedzi z metody serwisowej, która to zapisuje jest wyłowanie findById, ale doczytałem, że ona bierze rzeczy z cache Hibernate i tez może zwrócić, że obiekt z tym id istnieje a fizycznie nadal nie ma go w bazie,

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