java - ¿Cómo se propaga UserTransaction?
java-ee ejb (3)
Tengo un bean sin estado con transacciones gestionadas por bean, y un método como este:
@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();
}
}
Entonces, ¿cómo se propaga UserTransaction
al bean OtherStatelessBeanLocal
?
Basado en la especificación EJB, no puede pasar un contexto de transacción de un bean (en este caso, su clase principal ...) usando una transacción programática a otro bean (en este caso, otro) usando una transacción programmatic
El objeto UserTransaction
es un objeto suministrado por el contenedor que envuelve el acceso a las llamadas a la API que el contenedor usa internamente, específicamente javax.transaction.TransactionManager . El TransactionManager
tiene métodos como begin
, commit
, rollback
y javax.transaction.Transaction getTransaction()
Debajo de las cubiertas, el TransactionManager usará un ThreadLocal o una técnica similar para rastrear el estado actual de la transacción con el hilo. Los ThreadLocals son objetos muy simples que podrían describirse fácilmente como un static HashMap
que usa el nombre del hilo como la clave y un objeto de su elección como el valor. Mientras permanezca en el mismo hilo, puede obtener el objeto desde cualquier punto de la cadena de invocación. Esta es una de las razones por las que no está permitido iniciar subprocesos en un entorno Java EE.
La propagación de la seguridad funciona de manera similar, al igual que las búsquedas JNDI que apuntan mágicamente al espacio de nombres java:comp/env
del componente o componente correcto. La conclusión es que no puede implementar un servidor de aplicaciones sin ThreadLocals. La propagación suena más activa de lo que es, cuando en realidad es simplemente el hecho de no dejar el hilo para que el contenedor y todos los involucrados aún puedan encontrar sus "cosas".
De nuevo en términos de administración de transacciones, el objeto que un TransactionManager rastreará en su ThreadLocal típicamente implementará (directa o indirectamente) las interfaces Transaction y TransactionSynchronizationRegistry . Entre estas dos interfaces, el contenedor tiene todos los enlaces que necesita para rastrear DataSource
s, EntityManager
y otros recursos en la transacción actual en su nombre. Estas interfaces también permiten que el contenedor ofrezca devoluciones de llamada como SessionSynchronization , así como medios para hacer otras cosas en su nombre al finalizar la transacción, como vaciar / cerrar EntityManagers, enviar mensajes pendientes de JMS y conservar los temporizadores creados por su aplicación en el curso. de la transacción.
Para EJB3, normalmente se define la propagación de transacciones con la anotación @TransactionAttribute.
El atributo de transacción predeterminado para todas las aplicaciones EJB 3.0 es REQUERIDO:
Si un cliente invoca el método del bean empresarial mientras el cliente está asociado con un contexto de transacción, el contenedor invoca el método del bean empresarial en el contexto de transacción del cliente.
Los documentos para el tipo de transacción están aquí: http://download.oracle.com/javaee/6/api/javax/ejb/TransactionAttributeType.html
Nota: el contexto de persistencia y la propagación de transacciones suelen suceder juntos, pero no siempre. Por ejemplo, los beans de sesión con estado pueden tener un contexto de persistencia extendida .