EJB - Transazioni

Una transazione è una singola unità di elementi di lavoro, che segue le proprietà ACID. ACID sta per Atomic, Consistent, Isolated e Durable.

  • Atomic- Se uno qualsiasi degli elementi di lavoro fallisce, l'intera unità sarà considerata guasta. Il successo significa che tutti gli elementi vengono eseguiti correttamente.

  • Consistent - Una transazione deve mantenere il sistema in uno stato coerente.

  • Isolated - Ogni transazione viene eseguita indipendentemente da qualsiasi altra transazione.

  • Durable - La transazione dovrebbe sopravvivere a un errore di sistema se è stata eseguita o commessa.

I contenitori / server EJB sono server delle transazioni e gestiscono la propagazione del contesto delle transazioni e le transazioni distribuite. Le transazioni possono essere gestite dal contenitore o dalla gestione del codice personalizzato nel codice del bean.

  • Container Managed Transactions - In questo tipo, il contenitore gestisce gli stati della transazione.

  • Bean Managed Transactions - In questo tipo, lo sviluppatore gestisce il ciclo di vita degli stati delle transazioni.

Transazioni gestite dal container

EJB 3.0 ha specificato i seguenti attributi delle transazioni, che i contenitori EJB implementano:

  • REQUIRED - Indica che il metodo aziendale deve essere eseguito all'interno della transazione, altrimenti verrà avviata una nuova transazione per quel metodo.

  • REQUIRES_NEW - Indica che deve essere avviata una nuova transazione per il metodo commerciale.

  • SUPPORTS - Indica che il metodo aziendale verrà eseguito come parte della transazione.

  • NOT_SUPPORTED - Indica che il metodo aziendale non deve essere eseguito come parte della transazione.

  • MANDATORY - Indica che il metodo aziendale verrà eseguito come parte della transazione, altrimenti verrà generata un'eccezione.

  • NEVER - Indica se il metodo aziendale viene eseguito come parte della transazione, verrà generata un'eccezione.

Esempio

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
   }
}

Il metodo aziendale createUserDetail () viene reso obbligatorio utilizzando l'annotazione obbligatoria.

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();
   }
}

Il metodo aziendale createUser () utilizza createUserDetail (). Se si è verificata un'eccezione durante la chiamata a createUser () e l'oggetto Utente non viene creato, anche l'oggetto UserDetail non verrà creato.

Transazioni gestite da bean

Nelle transazioni gestite da bean, le transazioni possono essere gestite gestendo le eccezioni a livello di applicazione.

Di seguito sono riportati i punti chiave da considerare:

  • Start - Quando avviare una transazione in un metodo aziendale.

  • Sucess - Identifica lo scenario di successo quando deve essere eseguito il commit di una transazione.

  • Failed - Identifica lo scenario di errore quando una transazione deve essere ripristinata.

Esempio

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{
   }
}

In questo esempio, abbiamo utilizzato UserTransaction interfaccia per contrassegnare l'inizio della transazione utilizzando userTransaction.begin()chiamata al metodo. Contrassegniamo il completamento della transazione, utilizzandouserTransaction.commit() e se si verifica un'eccezione durante la transazione, eseguiamo il rollback dell'intera transazione utilizzando userTransaction.rollback() chiamata al metodo.