Zbierałem informacje o metodzie flush (), ale nie jestem do końca jasne, kiedy jej używać i jak używać jej poprawnie. Z tego, co przeczytałem, rozumiem, że zawartość kontekstu trwałości będzie synchronizowana z bazą danych, tj. Wydawanie zaległych oświadczeń lub odświeżanie danych encji.
Teraz mam następujący scenariusz z dwoma podmiotami A
i B
(w relacji jeden do jednego, ale nie wymuszony ani modelowany przez JPA). A
ma złożoną PK, która jest ustawiana ręcznie, a także ma automatycznie generowane pole IDENTITY recordId
. To recordId
powinno być napisane do podmiotu B
jako obcego-klucz do A
. Oszczędzam A
i to B
w jednej transakcji. Problem polega na tym, że wartość generowane automatycznie A.recordId
nie są dostępne w ramach transakcji, chyba że zrobić wyraźne wezwanie em.flush()
po wywołaniu em.persist()
na A
. (Jeśli mam automatycznie wygenerowany identyfikator PK IDENTITY, wartość jest bezpośrednio aktualizowana w encji, ale tak nie jest w tym przypadku).
Może em.flush()
wyrządzić jakąś szkodę podczas używania go w ramach transakcji?
źródło
W rzeczywistości
em.flush()
rób więcej niż tylko wysyłanie buforowanych poleceń SQL. Próbuje zsynchronizować kontekst trwałości z bazową bazą danych. Może to spowodować duże zużycie czasu w procesach, jeśli pamięć podręczna zawiera kolekcje do synchronizacji.Ostrożność podczas korzystania z niego.
źródło
Tak, może utrzymywać blokady w bazie danych dłużej niż to konieczne.
Ogólnie rzecz biorąc, podczas korzystania z JPA delegujesz zarządzanie transakcjami do kontenera (aka CMT - przy użyciu adnotacji @Transactional w metodach biznesowych), co oznacza, że transakcja jest automatycznie uruchamiana po wprowadzeniu metody i zatwierdzana / wycofywana na końcu. Jeśli pozwolisz EntityManagerowi obsłużyć synchronizację bazy danych, wykonanie instrukcji sql zostanie wyzwolone tylko tuż przed zatwierdzeniem, co doprowadzi do krótkotrwałych blokad w bazie danych. W przeciwnym razie ręcznie przepłukane operacje zapisu mogą zachować blokady między ręcznym opróżnieniem a automatycznym zatwierdzeniem, które mogą być długie w zależności od pozostałego czasu wykonania metody.
Zauważa, że niektóre operacje automatycznie wyzwalają opróżnianie: wykonanie natywnego zapytania w tej samej sesji (stan EM musi zostać opróżniony, aby było osiągalne przez zapytanie SQL), wstawianie jednostek przy użyciu natywnego generowanego identyfikatora (generowanego przez bazę danych, więc instrukcja insert musi być wyzwalane, dzięki czemu EM jest w stanie pobrać wygenerowany identyfikator i odpowiednio zarządzać relacjami)
źródło