Transacciones de Yakarta - Jakarta Transactions
Las Transacciones Jakarta ( JTA , anteriormente Java Transaction API), una de las Jakarta EE API , permite transacciones distribuidas que se harán a través de múltiples X / Open XA recursos de Java medio ambiente. JTA fue una especificación desarrollada bajo el Proceso de la Comunidad Java como JSR 907. JTA proporciona:
- demarcación de los límites de las transacciones
- X / Open XA API que permite que los recursos participen en las transacciones.
Arquitectura X / Open XA
En la arquitectura X / Open XA, un administrador de transacciones o un monitor de procesamiento de transacciones (monitor TP) coordina las transacciones en varios recursos, como bases de datos y colas de mensajes. Cada recurso tiene su propio administrador de recursos. El administrador de recursos normalmente tiene su propia API para manipular el recurso, por ejemplo, la API de JDBC para trabajar con bases de datos relacionales. Además, el administrador de recursos permite que un monitor de TP coordine una transacción distribuida entre su propio administrador y otros administradores de recursos. Finalmente, está la aplicación que se comunica con el monitor de TP para comenzar, confirmar o revertir las transacciones. La aplicación también se comunica con los recursos individuales utilizando su propia API para modificar el recurso.
Implementación JTA de la arquitectura X / Open XA
La API de JTA consta de clases en dos paquetes de Java :
El JTA se basa en la arquitectura X / Open XA, pero define dos API diferentes para demarcar los límites de las transacciones. Distingue entre un servidor de aplicaciones , como un servidor EJB, y un componente de aplicación. Proporciona una interfaz, javax.transaction.TransactionManagerque es utilizada por el propio servidor de aplicaciones para comenzar, confirmar y revertir las transacciones. Proporciona una interfaz diferente, la javax.transaction.UserTransaction, que utiliza el código de cliente general, como un servlet o un EJB, para gestionar las transacciones.
La arquitectura JTA requiere que cada administrador de recursos implemente la javax.transaction.xa.XAResourceinterfaz para que el supervisor de TP la administre. Como se indicó anteriormente, cada recurso tendrá su propia API específica, por ejemplo:
- las bases de datos relacionales usan JDBC
- los servicios de mensajería utilizan JMS
- Los recursos generalizados de EIS ( Enterprise Information System ) utilizan la API del conector Java EE .
Interfaz de programación de aplicaciones
La API de transacciones de Jakarta consta de tres elementos: una interfaz de demarcación de transacciones de aplicaciones de alto nivel, una interfaz de administrador de transacciones de alto nivel destinada a un servidor de aplicaciones y un mapeo estándar de Java del protocolo X / Open XA destinado a un administrador de recursos transaccionales.
Interfaz UserTransaction
La javax.transaction.UserTransactioninterfaz proporciona a la aplicación la capacidad de controlar los límites de las transacciones mediante programación. Esta interfaz puede ser utilizada por programas cliente Java o beans EJB.
El UserTransaction.begin()método inicia una transacción global y asocia la transacción con el hilo de llamada. La asociación de transacción a subproceso es administrada de forma transparente por el Administrador de transacciones.
No se requiere soporte para transacciones anidadas. El método UserTransaction.begin lanza la NotSupportedException cuando el hilo de llamada ya está asociado con una transacción y la implementación del administrador de transacciones no admite transacciones anidadas.
La propagación del contexto de transacción entre programas de aplicación es proporcionada por las implementaciones del administrador de transacciones subyacentes en las máquinas cliente y servidor. El formato de contexto de transacción utilizado para la propagación depende del protocolo y debe negociarse entre el cliente y el servidor. Por ejemplo, si el administrador de transacciones es una implementación de la especificación JTS , utilizará el formato de propagación del contexto de la transacción como se especifica en la especificación CORBA OTS 1.1. La propagación de transacciones es transparente para los programas de aplicación.
@Anotación transaccional
La javax.transaction.Transactionalanotación proporciona a la aplicación la capacidad de controlar los límites de las transacciones de forma declarativa. Esta anotación se puede aplicar a cualquier clase que la especificación de Jakarta EE defina como un bean administrado (que incluye beans administrados por CDI).
El siguiente ejemplo de código ilustra el uso de @Transactional en un bean administrado por CDI con alcance de solicitud:
@RequestScoped
public class ExampleBean {
@Transactional
public void foo() { // A transaction is active here
// Do work
} // After the method returns transaction is committed or rolled back
}
El comportamiento transaccional se puede configurar mediante un atributo en la anotación. Las opciones disponibles reflejan de cerca las de la especificación EJB .
@TransactionScoped anotación
La javax.transaction.TransactionScopedanotación proporciona a la aplicación la capacidad de declarar que el alcance durante el cual vive un bean está vinculado al tiempo que una transacción determinada está activa.
El siguiente ejemplo de código ilustra el uso de @TransactionScoped en un bean administrado CDI con alcance de solicitud:
@TransactionScoped
public class TxScopedBean {
public int number;
public int getNumber() {return number;}
public void setNumber(int number) {this.number = number;}
}
@RequestScoped
public class ExampleBean {
@Inject
private TxScopedBean txScopedBean;
@Transactional
public void foo() {
txScopedBean.setNumber(1);
}
@Transactional
public void bar() {
System.out.print(tXscopedBean.getNumber());
}
}
Si el método foo () se llama primero en una instancia administrada de ExampleBean y luego se llama al método bar () , el número impreso será 0 y no 1. Esto se debe a que cada método tenía su propia transacción y, por lo tanto, su propia instancia de TxScopedBean . Por lo tanto, el número 1 que se estableció durante la llamada a foo () no se verá durante la llamada a bar () .
Soporte de UserTransaction en el servidor EJB
Los servidores EJB deben admitir la interfaz UserTransaction para que la utilicen los beans EJB con el valor BEAN en la javax.ejb.TransactionManagement anotación (esto se denomina transacciones gestionadas por bean o BMT). La interfaz UserTransaction se expone a los componentes EJB a través de la interfaz EJBContext mediante el método getUserTransaction, o directamente mediante inyección mediante la @Resourceanotación general . Por lo tanto, una aplicación EJB no interactúa con Transaction Manager directamente para la demarcación de transacciones; en su lugar, el bean EJB se basa en el servidor EJB para proporcionar soporte para todo su trabajo de transacciones como se define en la especificación Jakarta Enterprise Beans. (La interacción subyacente entre el servidor EJB y la TM es transparente para la aplicación; la carga de implementar la gestión de transacciones recae en el contenedor EJB y el proveedor del servidor).
El siguiente ejemplo de código ilustra el uso de UserTransaction a través de transacciones gestionadas por bean en un bean de sesión EJB:
@Stateless
@TransactionManagement(BEAN)
public class ExampleBean {
@Resource
private UserTransaction utx;
public void foo() {
// start a transaction
utx.begin();
// Do work
// Commit it
utx.commit();
}
}
Alternativamente, UserTransaction se puede obtener de SessionContext:
@Stateless
@TransactionManagement(BEAN)
public class ExampleBean {
@Resource
private SessionContext ctx;
public void foo() {
UserTransaction utx = ctx.getUserTransaction();
// start a transaction
utx.begin();
// Do work
// Commit it
utx.commit();
}
}
Sin embargo, @TransactionManagement(BEAN)tenga en cuenta que en el ejemplo anterior, si se omite la anotación, una transacción JTA se inicia automáticamente cada vez que foo()se llama y se confirma o revierte automáticamente cuando foo()se sale. Por lo tanto, hacer uso de UserTransaction no es necesario en la programación EJB, pero podría ser necesario para un código muy especializado.
Soporte de UserTransaction en JNDI
UserTransaction debería estar disponible en java:comp/UserTransaction(si se instala una implementación de JTA en el entorno).