2010-11-07 19 views
16

J'ai un bean sans état des transactions gérées par le bean, et une méthode comme ceci:Comment UserTransaction se propage?

@Stateless 
@TransactionManagement(TransactionManagementType.BEAN) 
public class ... { 

    @Resource 
    private UserTransaction ut; 
    @EJB 
    private OtherStatelessBeanLocal other; 

    public void invokeSomeMethods() 
     ut.begin(); 
     ... 

     // invoke other bean's methods here. 
     other.method(); 

     ... 
     ut.commit(); 

    } 

} 

Alors, comment le UserTransaction propagées à la fève OtherStatelessBeanLocal?

+0

ça ne marche pas, non? –

Répondre

32

L'objet UserTransaction est un objet fourni par le conteneur qui enveloppe l'accès aux appels API que le conteneur utilise en interne, en particulier javax.transaction.TransactionManager. Le TransactionManager a des méthodes telles que begin, commit, rollback et javax.transaction.Transaction getTransaction()

Sous les couvertures, le TransactionManager utilisera une technique ThreadLocal ou similaire pour suivre l'état de transaction en cours avec le fil. ThreadLocals sont des objets très simples qui peuvent facilement être décrits comme un static HashMap qui utilise le nom du thread comme clé et un objet de votre choix comme valeur. Tant que vous restez dans le même thread, vous pouvez obtenir l'objet à partir de n'importe quel point de la chaîne d'invocation. C'est l'une des raisons pour lesquelles il n'est pas autorisé de démarrer des threads dans un environnement Java EE.

La propagation de la sécurité fonctionne de la même manière, tout comme les recherches JNDI qui pointent comme par magie vers l'espace de noms java:comp/env du module ou du module droit. En bout de ligne, vous ne pouvez pas implémenter un serveur d'applications sans ThreadLocals. La propagation semble plus active qu'elle ne l'est, alors qu'en réalité c'est simplement l'acte de ne pas laisser le fil de sorte que le conteneur et tous ceux qui sont impliqués peuvent toujours trouver votre "truc". En termes de gestion des transactions, l'objet qu'un TransactionManager suivra dans son ThreadLocal implémentera (directement ou indirectement) les deux interfaces Transaction et TransactionSynchronizationRegistry. Entre ces deux interfaces, le conteneur a tous les hooks dont il a besoin pour suivre DataSource s, EntityManager s et d'autres ressources dans la transaction en cours pour votre compte. Ces interfaces permettent également au conteneur d'offrir des rappels tels que SessionSynchronization, ainsi que des moyens de faire d'autres choses en votre nom à la fin de la transaction, comme le vidage/fermeture des EntityManagers, l'envoi de messages JMS en attente et la persistance des Timers créés par votre application. de la transaction.

+2

La réponse parfaite.+1 –

+0

En fait non, car il n'applique pas les connaissances à la question posée. – Thomas

0

Pour EJB3, vous définissez normalement la propagation de transaction avec l'annotation @TransactionAttribute.

L'attribut transaction par défaut pour toutes les applications EJB 3.0 est nécessaire:

Si un client invoque la méthode du bean entreprise alors que le client est associé à un contexte de transaction, le conteneur invoque la méthode du bean entreprise dans du client contexte de transaction.

pour le type de transaction de la doc sont ici: http://download.oracle.com/javaee/6/api/javax/ejb/TransactionAttributeType.html

N.B. Le contexte de persistance et la propagation des transactions se produisent généralement ensemble mais pas toujours - méfiez-vous. Par exemple, les beans de session avec état peuvent avoir un extended persistence context.

+0

Remarque dans le cas du contexte de persistance EXTENDED, le contexte de persistance est toujours associé exclusivement à la transaction et non disponible pour les autres transactions, car dès lors que le bean @Stateful détenteur est impliqué dans la transaction, il n'est pas autorisé à quitter transaction jusqu'à ce qu'elle s'engage ou rollsback. Toutes les demandes sur ce bean @Stateful à l'extérieur de la transaction attendront la durée de @AccessTimeout avant de finalement lancer une forme de ConcurrentAccessException. –

4

Basé sur la spécification EJB, vous ne pouvez pas passer un contexte de transaction d'un haricot (dans ce cas, votre classe principale ...) à l'aide programmatique des transactions dans un autre bean (dans ce cas, d'autres) à l'aide programmatique des transactions bien