Transazioni EJB in chiamate metodo-locali

Nella seguente configurazione, il metodo B viene eseguito in una (nuova) transazione?

Un bean, con due metodi, metodo A e metodo B

public class MyEJB implements SessionBean public void methodA() { doImportantStuff(); methodB(); doMoreImportantStuff(); } public void methodB() { doDatabaseThing(); } } 

L’EJB è gestito dal contenitore, con methodB nella transazione require_new e il metodo A nella transazione richiesta. in tal modo:

   MyName * Required   MyName methodB  RequiresNew  

Ora lascia che sia un altro metodo di chiamata EJB con una chiamata al metodo EJB. methodA ora viene eseguito in una transazione. La chiamata successiva al metodoB dal metodoA verrà eseguita nella stessa transazione o verrà eseguita in una nuova transazione? (attenzione, è il codice attuale qui. Non esiste una chiamata ejb esplicita al metodo B)

La chiamata al methodB() è una normale chiamata di un metodo, non intercettata dal contenitore EJB; in fase di esecuzione il contenitore EJB inietterà un proxy e non un’istanza della class, questo è il modo in cui intercetta le chiamate e imposta l’ambiente prima di chiamare il metodo. Se lo usi, stai chiamando un metodo direttamente e non attraverso il proxy. Quindi entrambi i metodi useranno la stessa transazione, indipendentemente da ciò che è definito in ejb-jar.xml per le chiamate attraverso le interfacce EJB.

iniettare SessionContext e chiedergli l’istanza proxy:

 @Stateless public class UserFacade implements UserFacadeLocal { @Resource private SessionContext context; @Override @TransactionAttribute(TransactionAttributeType.REQUIRED) private void create(User user) { System.out.println("Users Count: "+count()); //invocation#1 System.out.println("Users Count Through Context: "+context.getBusinessObject(UserFacadeLocal.class).count()); //invocation#2 } @Override @TransactionAttribute(TransactionAttributeType.NEVER) public int count() { return ((Long) q.getSingleResult()).intValue(); } } 

in “invocazione n. 1” si tratta di una chiamata locale, che non passa per il proxy, restituirà il conteggio

in ‘invocation # 2’ si tratta di una chiamata attraverso il proxy, e quindi si annota non per supportare la transazione -che è ora aperta dal metodo create (utente )-, questa invocazione genererà un’eccezione di transazione:

javax.ejb.EJBException: EJB non può essere richiamato nella transazione globale

Useranno la stessa transazione.

Se ricordo bene, la transazione è avviata dal contenitore “prima” il metodo è invocato e impegnato dopo “finire”.

Poiché “a” chiama “b”, “b” usa la stessa transazione.

:S

Credo che la cosa migliore che puoi fare è testarlo per verificarlo! 🙂