Por ejemplo, si tenemos que hacer una transferencia de una cuenta a otra en un banco, las dos operaciones forman un conjunto. No sería lógico que quitásemos efectivo de una cuenta y, por alguna razón, no pudiéramos ingresar el dinero en la cuenta de destino, o se realizan las dos operaciones o ninguna.
Una vez iniciada una transacción, ningún cambio queda reflejado hasta que no se confirmen las operaciones ("commit"), o se anulen las mismas ("rollback").
El API de Java para manipular transacciones se conoce como JTA (Java Transaction Api).
Existen tres conceptos de transacciones que son importantes para el desarrollo de aplicaciones Java EE.
- Atomicidad.
Las
operaciones son un conjunto completo, o todas se realizan bien o si
falla alguna, fallan todas a la vez.
- Locking
and Isolation. Dicho
término implica que solamente una transacción puede actualizar un
dato al mismo tiempo.
- Modelo.
Cuantas
transacciones pueden estar activas en un mismo thread (hilo) en
particular en un momento dato.
- Anidado
(Nested). Una transacción consta de varias sus transacciones que
corren en paralelo todas juntas.
- Encadenado
(Chained). Una transacción consta de varias subtransacciones que
corren en secuencia.
- Plano
(Flat): Una transacción no puede contener subtransacciones. La
plataforma Java EE solamente soporta el modelo plano.
- Transaction
Manager (TM): Es el encargado de proveer los servicios para
demarcación de transacciones, manejo de recursos transaccionales,
sincronización y propagación de contexto transaccional.
- Application
Server: Implementa los servicios necesarios para proveer un entorno
de ejecución para las aplicaciones. Entre estos servicios está el
manejo del estado transaccional.
- Resource
Manager (RM): Ofrece a las aplicaciones acceso a recursos. Este
acceso se ofrece a través de Resource Adapters. Este participa de
transacciones implementado una interfaz para el manejo de recursos
transaccionales, que controla la asociación a una transacción, la
finalización de una transacción y la recuperación de una
transacción.
- Aplicación
basada en componentes transaccionales: Esta aplicación se ejecuta
sobre un servidor de aplicaciones, el cual le ofrece, entre otros
servicios, control de transacciones, como por ejemplo, una
aplicación basada en Enterprise Java Bean.
- Communication
Resource Manager: Encargado de la propagación del contexto
transaccional permitiendo acceder a recursos transaccionales
ubicados en otros dominios.
- Mediante
programación. Existe un bean que controla la transacción. Esta
forma se llama Bean-Managed Transaction (BMT).
- De
forma declarativa. El desarrollador solamente debe establecer de
forma declarativa como quiere que el contenedor maneje las
transacciones. Esta forma lleva el nombre de Container-Managed
Transactions (CMT).
Atributos de Transacciones
Los atributos de las transacciones se especifican mediante anotaciones u opcionalmente, en un deployment descriptor. Las anotaciones de los atributos son las siguientes:Required @TransactionAttribute(REQUIRED) Si un cliente está corriendo dentro una transacción e
invoca un método de un bean, el método se ejecuta dentro de la
misma transacción.
RequiresNew @TransactionAttribute(REQUIRES_NEW)
Si un cliente está corriendo dentro de una transacción e invoca un
método, la transacción del cliente se suspende, se inicia una
nueva, la cual se termina al finalizar el método y se reinicia la
transacción del cliente.
Mandatory @TransactionAttribute(MANDATORY) Mandatory @TransactionAttribute(MANDATORY)
Si el cliente está corriendo dentro una transacción e invoca un método
de un bean, el método se ejecuta dentro de la misma transacción.
NotSupported @TransactionAttribute(NOT_SUPPORTED).
Si
el cliente está corriendo dentro de una transacción e invoca un
método, la transacción del cliente se suspende, cuando termina el
método, la transacción del cliente se reanuda.
Si el cliente no está asociado a una transacción, el contenedor no inicia una nueva.
Supports @TransactionAttribute(SUPPORTS)
Si
el cliente está corriendo dentro una transacción e invoca un método
de un bean, el método se ejecuta dentro de la misma transacción.
Si
el cliente no está asociado con una transacción, el contenedor no
inicia una nueva.Never @TransactionAttribute(NEVER)
Ejemplo
de código de una transacción:
@TransactionAttribute(NOT_SUPPORTED)
@Stateful
public class BeanTransacciones implements Transaction {
...
@TransactionAttribute(REQUIRES_NEW) @TransactionAttribute(REQUIRES_NEW)
public void PrimerMetodo() {...}
@TransactionAttribute(REQUIRED)
public void SegundoMetodo() {...}
public void TercerMetodo() {...}
public void CuartoMetodo() {...}
}
Para
delimitar las transacciones JTA, se utilizan los siguientes métodos
de la interfaz javax.transaction.UserTransaction:- begin
- commit
- rollback
Ejemplo:
import java.util.*;
import javax.ejb.*;
import java.sql.*;
import javax.sql.*;
import javax.naming.*;
import javax.transaction.*;
@Stateless
@TransactionManagement(BEAN)
public class BeanStock implements Stock {
@Resource javax.Transaction.UserTransaction mitransaccion;
@Resource javax.sql.DataSource ds1;
public void updateStock(int idstock, double precio) {
Connection con = null;
PreparedStatement prepStmt = null;
try {
con = ds1.getConnection();
mitransaccion.begin();
prepStmt = con.prepareStatement(
"UPDATE Stock set precio = ? where IdStock = ?");
prepStmt.setDouble(1, precio);
prepStmt.setInt(2, idstock);
int registrosafectados = prepStmt.executeUpdate();
mitransaccion.commit();
} catch (Exception ex) {
try {
mitransaccion.rollback();
} catch (SystemException ex) {
throw new EJBException ("Rollback ha fallado: " + ex.getMessage();
}
throw new EJBException("La transaccion ha fallado: " + ex.getMessage());
} finally {
try {
prepStmt.close();
con.close();
} catch (SQLException ex) {
throw new EJBException ("Error al cerrar la conexion: " + e.getMessage());
}
}
}