2013-04-27 15 views
5

Powiedzmy mamy następujący fragment kodu:Czy nowa transakcja odrywa wszystkie poprzednie jednostki?

@Entity 
public class User { 
    @Id 
    private String name; 
    @OneToOne(cascade = CascadeType.ALL) 
    private Address address; 
    //getters and setters 
} 

@Entity 
public class Address { 
    @Id 
    private int id; 
    private String street; 
    //getters and setters 
} 

@Stateless 
//@Service 
public class UserLogicClass { 
    @PersistenceContext 
    //@Autowired 
    private EntityManager entityManager; 

    public void logicOnUser(User user) { 
     if(logicOnAddress(user.getAddress()) { 
      otherLogicOnUser(user); 
     } 
    } 

    public boolean logicOnAddress(Address address) { 
     // 
     entityManager.find(address);//address becomes managed 
     // 
    } 

    @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) 
    //@Transactional(propagation = Propagation.REQUIRES_NEW) 
    public void otherLogicOnUser 
    // 
     entityManager.find(user);/*without annotation, user is not managed and address is managed, but with the transaction annotation is the address still managed?*/ 
    // 
    } 
} 

Kwestia polega na komentarz z ostatniej metody; Jestem ciekawostką, co dzieje się w przypadku Spring i EJB. Załóżmy, że Spring jest skonfigurowany z transakcjami JTA i każda metoda wywołana z tej klasy rozpocznie nową transakcję, tak jak w EJB.

Odpowiedz

5

To bardziej kwestia WZP. EntityManager nie jest propagowana do nowej transakcji, chyba że zrobisz to rozszerzony:

@PersistenceContext(type = PersistenceContextType.EXTENDED) 
//@Autowired 
private EntityManager entityManager; 

Cytat specyfikacji JPA 2.0:

Pojemnik zarządzane kontekst wytrwałość może być zdefiniowana mieć albo całe życie ma zasięg do pojedynczej transakcji lub wydłużony okres istnienia obejmujący wiele transakcji, w zależności od parametru PersistenceContextType określonego w chwili utworzenia menedżera encji . Ta specyfikacja odnosi się do takich kontekstów trwałości, jak konteksty utrwalania o zasięgu transakcji i konteksty o przedłużonej trwałości, odpowiednio.

+0

Więc jeśli typ jest ustawiony na rozszerzony, wewnątrz tej metody, nowa jednostka jest tworzona menedżer, który nie ma żadnych zarządzanych podmiotów? – m3th0dman

+1

Tak, dokładnie. W metodzie 'otherLogicOnUser' tworzona jest nowa transakcja, a kontekst utrwalania nie powinien być propagowany, chyba że zostanie przedłużony. – dcernahoschi

+0

Użycie rozszerzonego EntityManager zostało zaprojektowane do użycia w Stateful EJB, nie jest bezpieczne dla wątków, a kolizje kontekstu utrwalania mogą powstać, jeśli metoda używająca EntityManager o zakresie transakcji wywołuje metodę przy użyciu rozszerzonego EntityManager w tej samej transakcji. – German

5

Uwaga: Ponieważ mechanizm ten opiera się na proxy, tylko „zewnętrzne” metoda połączeń wpadającym przez pełnomocnika zostaną przechwycone. Oznacza to, że "samo wywołanie", tj. Metoda w obiekcie docelowym wywołująca inny sposób obiektu docelowego, nie doprowadzi do rzeczywistej transakcji w czasie wykonywania, nawet jeśli wywołana metoda jest oznaczona jako @ Transactional!

otherLogicOnUser() jest wywoływany wewnątrz obiektu docelowego.

Więcej: EJB Transactions in local method-calls

Powiązane problemy