2009-10-08 13 views
0

J'essaie de comprendre pleinement la démarcation JTA avec CMT. Le comportement que je rencontre est que seul le premier @TransactionAttribute de la méthode est respecté sur l'EJB et que les invocations de méthodes suivantes du même bean avec des annotations @TransactionAttribute différentes ne le sont pas.Où exactement la démarcation des transactions JTA pour CMT est-elle respectée?

Exemple:

@Stateless 
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED) 
public class Foo implements IFoo { 

    @EJB 
    private IBar barBean; 

    // inherits class transaction annotation of NOT_SUPPORTED 
    public void doSomething() { 
     barBean.doAction(); 
    } 
} 

@Stateless 
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED) 
public class Bar implements IBar { 

    public void doAction() { 
     Entity entity = bar.find(); 
     entity.setName("new name"); 
     // fails with EJBException with TransactionRequiredException as cause 
     save(entity); 
    } 

    public Entity find() { 
     // return some persisted entity. 
     return em.findById(1); 
    } 

    @TransactionAttribute(TransactionAttributeType.REQUIRED) 
    public Entity save(entity) { 
     em.persist(em.merge(entity)); 
     em.flush(); 
    } 
} 

Le comportement que je vois est que Bar.save() jette un TransactionRequiredException. Cela m'indique que l'annotation REQUIRED définie sur save() ne crée pas de transaction. REQUIRES_NEW ne fonctionne pas non plus. Si je déplace le save() vers un autre EJB, cela fonctionne comme prévu. Cela signifie-t-il que seule la première annotation TransactionAttribute est respectée indépendamment des invocations de méthodes ultérieures sur la même chose avec des valeurs d'annotation différentes? Est-ce un bug ou le comportement attendu? Je n'arrive pas à trouver de documentation qui explique cela concrètement. J'apprécie tout aperçu à ce sujet.

Ma pile: EJB 3.0, Toplink Essentials, GF V2UR2

Répondre

2

Ma lecture de la spécification EJB 3 est que la spécification de transaction sur une méthode individuelle remplace celle de l'EJB dans son ensemble. Par conséquent vos attentes que REQUIRED devrait s'appliquer semblent raisonnables, mais ...

ceci est seulement si vous employez la méthode de haricot comme EJB. Lorsque vous effectuez un appel direct d'une méthode métier doAction() à une autre, save(), vous n'utilisez pas de référence EJB et par conséquent, il s'agit simplement de Java ancien - le conteneur n'est pas impliqué, donc aucune opportunité pour le conteneur d'intervenir .

Si vous appliquez l'option requise à la méthode doAction(), cela devrait fonctionner.

Cette théorie est cohérente avec vos résultats de l'effet de refactoring à un autre EJB. Djna - Merci pour votre réponse.

+0

Votre explication a du sens. J'ai été en mesure de toucher la base avec un autre collègue et il a également été d'accord avec votre déclaration. J'apprécie votre temps. – Hoon