ejemplo java-ee transactions ejb

java-ee - ejemplo - @ejb



Transacciones EJB en llamadas a métodos locales (3)

En la siguiente configuración, ¿se ejecuta el método B en una (nueva) transacción?

Un EJB, que tiene dos métodos, el método A y el método B

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

El EJB está gestionado por contenedor, con el método B en require_new transaction y el método A en la transacción requerida. así:

<container-transaction id="MethodTransaction_1178709616940"> <method id="MethodElement_1178709616955"> <ejb-name>MyName</ejb-name> <method-name>*</method-name> <trans-attribute>Required</trans-attribute> </method> <method id="MethodElement_1178709616971"> <ejb-name>MyName</ejb-name> <method-name>methodB</method-name> </method> <trans-attribute>RequiresNew</trans-attribute> </container-transaction>

Ahora permita que otro EJB llame al método A con una llamada a un método EJB. methodA ahora se ejecuta en una transacción. ¿Se ejecutará la llamada subsiguiente al método B del método A en la misma transacción, o se ejecutará en una nueva transacción? (mente, es el código real aquí. No hay una llamada ejb explícita al método B)


Utilizarán la misma transacción.

Si recuerdo bien, la transacción se inicia con el contenedor "antes", el método se invoca y se confirma después de que "finaliza".

Como "a" llama "b", "b" usaría la misma transacción.

: S

¡Supongo que lo mejor que puedes hacer es probarlo para verificarlo! :)


Su llamada al methodB() es una llamada ordinaria de un método, no interceptada por el contenedor EJB; en tiempo de ejecución, el contenedor EJB inyectará un proxy y no una instancia de su clase, esta es la forma en que intercepta las llamadas y configura el entorno antes de llamar a su método. Si usa this , está llamando a un método directamente y no a través del proxy. Por lo tanto, ambos métodos usarán la misma transacción, independientemente de lo que se define en ejb-jar.xml para llamadas a través de interfaces EJB.


Inyecte SessionContext y solicite su instancia de 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(); } }

en ''invocación n. ° 1'' se trata de una llamada local, que no pasa por el proxy, devolverá el recuento

en ''invocación n. ° 2'' se trata de una llamada a través del proxy y, por lo tanto, usted anota que no admite transacciones, que ahora se abre mediante el método de creación (usuario), esta invocación generará una excepción de transacción:

javax.ejb.EJBException: EJB no se puede invocar en una transacción global