EJB - Transacciones

Una transacción es una sola unidad de elementos de trabajo, que sigue las propiedades de ACID. ACID significa Atómico, Consistente, Aislado y Durable.

  • Atomic- Si alguno de los elementos de trabajo falla, toda la unidad se considerará fallada. El éxito significa que todos los elementos se ejecutan correctamente.

  • Consistent - Una transacción debe mantener el sistema en un estado consistente.

  • Isolated - Cada transacción se ejecuta independientemente de cualquier otra transacción.

  • Durable - La transacción debe sobrevivir a la falla del sistema si se ha ejecutado o confirmado.

EJB Container / Servers son servidores de transacciones y manejan la propagación del contexto de las transacciones y las transacciones distribuidas. Las transacciones pueden ser administradas por el contenedor o por manejo de código personalizado en el código de bean.

  • Container Managed Transactions - En este tipo, el contenedor gestiona los estados de la transacción.

  • Bean Managed Transactions - En este tipo, el desarrollador gestiona el ciclo de vida de los estados de las transacciones.

Transacciones gestionadas por contenedor

EJB 3.0 ha especificado los siguientes atributos de transacciones, que implementan los contenedores EJB:

  • REQUIRED - Indica que el método comercial debe ejecutarse dentro de la transacción; de lo contrario, se iniciará una nueva transacción para ese método.

  • REQUIRES_NEW - Indica que se va a iniciar una nueva transacción para el método comercial.

  • SUPPORTS - Indica que el método comercial se ejecutará como parte de la transacción.

  • NOT_SUPPORTED - Indica que el método comercial no debe ejecutarse como parte de la transacción.

  • MANDATORY - Indica que el método comercial se ejecutará como parte de la transacción; de lo contrario, se lanzará una excepción.

  • NEVER - Indica si el método comercial se ejecuta como parte de la transacción, entonces se lanzará una excepción.

Ejemplo

package com.tutorialspoint.txn.required;
 
import javax.ejb.*
 
@Stateless
@TransactionManagement(TransactionManagementType.CONTAINER)
public class UserDetailBean implements UserDetailRemote {
	
   private UserDetail;

   @TransactionAttribute(TransactionAttributeType.REQUIRED)
   public void createUserDetail() {
      //create user details object
   }
}

El método de negocio createUserDetail () se hace Obligatorio usando la anotación Requerida.

package com.tutorialspoint.txn.required;
 
import javax.ejb.*
 
@Stateless
public class UserSessionBean implements UserRemote {
	
   private User;

   @EJB
   private UserDetailRemote userDetail;

   public void createUser() {
      //create user 
      //...
      //create user details
      userDetail.createUserDetail();
   }
}

El método de negocio createUser () está utilizando createUserDetail (). Si se produjo una excepción durante la llamada a createUser () y no se crea el objeto User, tampoco se creará el objeto UserDetail.

Transacciones gestionadas por Bean

En Bean Managed Transactions, las transacciones se pueden administrar manejando excepciones a nivel de aplicación.

Los siguientes son los puntos clave a considerar:

  • Start - Cuándo iniciar una transacción en un método comercial.

  • Sucess - Identificar el escenario de éxito cuando se va a comprometer una transacción.

  • Failed - Identificar el escenario de falla cuando una transacción debe revertirse.

Ejemplo

package com.tutorialspoint.txn.bmt;
 
import javax.annotation.Resource;
import javax.ejb.Stateless;
import javax.ejb.TransactionManagement;
import javax.ejb.TransactionManagementType;
import javax.transaction.UserTransaction;
 
@Stateless
@TransactionManagement(value=TransactionManagementType.BEAN)
public class AccountBean implements AccountBeanLocal {
 
   @Resource
   private UserTransaction userTransaction;

   public void transferFund(Account fromAccount, double fund , 
      Account toAccount) throws Exception{

      try{
         userTransaction.begin();

         confirmAccountDetail(fromAccount);
         withdrawAmount(fromAccount,fund);

         confirmAccountDetail(toAccount);
         depositAmount(toAccount,fund);

         userTransaction.commit();
      }catch (InvalidAccountException exception) {
         userTransaction.rollback();
      }catch (InsufficientFundException exception) {
         userTransaction.rollback();
      }catch (PaymentException exception) {
         userTransaction.rollback();
      }
   }

   private void confirmAccountDetail(Account account) 
      throws InvalidAccountException {
   }

   private void withdrawAmount() throws InsufficientFundException {
   }

   private void depositAmount() throws PaymentException{
   }
}

En este ejemplo, hicimos uso de UserTransaction interfaz para marcar el comienzo de la transacción usando userTransaction.begin()llamada al método. Marcamos la finalización de la transacción, utilizandouserTransaction.commit() método y si ocurrió alguna excepción durante la transacción, entonces revertimos la transacción completa usando userTransaction.rollback() llamada al método.