Co się dzieje w tym scenariuszu jest regulowane przez:
- kontekście JPA Trwałość i jego relacji do transakcji JTA.
- Zachowanie parametru JA przekazywanie przez odniesienie "podobnie jak parametr przekazywanie lokalnych interfejsów. (patrz uwaga na przekazywany przez referencję na końcu tej odpowiedzi)
Tworzenie Entity Menedżer z @PersistenceContext
adnotacji prowadzi do powstania kierownika jednostki transakcja o zakresie i związanej z kontekstu utrwalania zdefiniowany przez persistence.xml
plik. Kontekst będzie śledzić jednostki typów określonych w Twojej persistence.xml
. Jednostka staje się zarządzana w tym kontekście po jej utrwaleniu, znalezieniu (em.find()
) lub scaleniu. Kontekst zostanie powiązany z bieżącą transakcją JTA. Po zakończeniu transakcji zmiany wprowadzone w kontekście utrwalania można przepłukać i zatwierdzić lub wycofać, jeśli sama transakcja zostanie wycofana.
W scenariuszu przykładowym przyjęto, że używany jest interfejs lokalny Bean2. Po wywołaniu Bean2-MethodB
rozpoczyna się nowa transakcja, ponieważ metoda jest opisana za pomocą @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
. Transakcja wywołującej metody jest zawieszona. Żaden kontekst utrwalania nie jest powiązany z nowo utworzoną transakcją. Jednak przekazana jednostka odwoła się do tej samej instancji podmiotu przetworzonego przez Bean1-MethodA
, a ta instancja jest jednostką zarządzaną w kontekście trwałości menedżera Entity Bean1. Tak więc, mimo że transakcja związana z tym kontekstem trwałości jest zawieszona, nie ma żadnych ograniczeń dotyczących modyfikowania tego obiektu z poziomu innej transakcji.
Tak więc nominalna sekwencja zdarzeń jest;
Bean1-MethodA
to się nazywa, rozpoczyna się TransactionA.
- Utworzono menedżera Entity-scoped Entity, kontekst utrwalania powiązany z TransactionA.
- dzwoni
Bean2MethodB
i przekazuje w "encji" jako parametr.
- Nowa transakcja - rozpoczęta transakcjaB, TransakcjaA zawieszone.
Bean2-MethodB
modyfikuje pole entity.name
.
- Bean2-MethodB kończy się, a TransactionB zatwierdza.
- Zatwierdzenie trwałości zasobów TransactionB JTA - Obiekt jest w kontekście utrwalania skojarzonym z transakcją A, więc nie został zatwierdzony.
- Bean1-MethodA wznawia działanie zgodnie z powiązaną transakcjąA.
- zmiany podmiotów, które w
Bean2-MethodB
są widoczne Bean1-MethodA
i kontekstu trwałości
Bean1-MethodA
wykończenia, TransactionA dopuszcza i zmienia kontekst utrzymywanie przepłukuje/zaangażowana w DB
- -> db zawiera zmiany pola wykonane w
Bean2-MethodB
Co stanie się po wycofaniu transakcji Bean2-MehodB?
Warto zauważyć, że jeśli zmiany pola jednostki są dokonywane w Bean2-MethodB
i Bean2-MethodB’s
wycofanie transakcji, zmiany w polach klasy nie są cofane. Wszystkie zasoby JTA zostaną wycofane, ale zmiany pola jednostki będą nadal odzwierciedlane w DB Jeśli Bean1-MehodA
zakończy się pomyślnie, co prowadzi do potencjalnych niespójności. Być może problemy z prawdziwym światem mogą wymusić takie rozwiązanie, ale prawdopodobnie lepiej zmodyfikować podmioty w transakcji, które mogą wycofać te zmiany.
Powyższe scenariusze były testowane na Eclipse Mars/WildFly8.2/HibernateJPA/Derby
Praca ze zdalnego EJB wywołuje
Tutaj parametr jednostka jest w odcinkach w rezultacie daje kopia podmiotu w Bean2-MethodB
. Ta kopia nie jest tym samym obiektem, który został użyty w Bean1-MethodA
, jest jednostką odłączoną i nie jest udostępniana z Bean1-MethodA
. (Jest to czasami znane jako pass-by-value, patrz uwaga na końcu tej odpowiedzi). Aby zmiany zostały odzwierciedlone w kontekście utrwalania Bean1-MethodA’s
, jednostka musiałaby zostać zwrócona do Bean1-MethodA
, a następnie scalona w kontekście utrwalania za pomocą menedżera jednostek. Łączenie to byłoby wymagane niezależnie od tego, czy zdalne wywołanie ejb zostało wykonane w ramach transakcji.
Uwaga dotycząca "Przekazywania" i "Przekazywania wartości".
Wszystkie parametry w java są z definicji przekazywane z wartością.Dla dobrej - rozszerzonej - dyskusji na temat przepełnienia stosu zobacz Is Java "pass-by-reference" or "pass-by-value"?. Ważne jest to, że dla lokalnych interfejsów, Java przekazuje kopię odniesienia - wskaźnik - do udostępnionej instancji - i to jest to, co ludzie często rozumieją jako "przekazywanie przez odniesienie". Zdalne interfejsy tworzą kopię instancji jednostki na zdalnym końcu, więc metoda wywołująca nie ma widoczności żadnych zmian w tej kopii. Jest to czasami znane jako wartość przejścia.
Właśnie dostałem ataku niepokoju JAVA po przeczytaniu odpowiedzi .. thx za wyjaśnienie – Bhuvan
http://stackoverflow.com/users/2410148/user2410148 - Nie ma za co - tak trochę trochę przerażające. Myślisz, że możesz zmień tytuł pytania na coś podobnego - EJB/JPA Transaction Boundaries -? Ponieważ to dokładniej odzwierciedla to, co mamy tutaj. Dzięki. – NickJI
zrobione ............ – Bhuvan