Spring - Gestión de transacciones

Una transacción de base de datos es una secuencia de acciones que se tratan como una sola unidad de trabajo. Estas acciones deben completarse por completo o no tener ningún efecto. La gestión de transacciones es una parte importante de la aplicación empresarial orientada a RDBMS para garantizar la integridad y coherencia de los datos. El concepto de transacciones se puede describir con las siguientes cuatro propiedades clave descritas comoACID -

  • Atomicity - Una transacción debe tratarse como una sola unidad de operación, lo que significa que la secuencia completa de operaciones es exitosa o no.

  • Consistency - Esto representa la consistencia de la integridad referencial de la base de datos, claves primarias únicas en tablas, etc.

  • Isolation- Puede haber muchos procesos de transacciones con el mismo conjunto de datos al mismo tiempo. Cada transacción debe aislarse de las demás para evitar la corrupción de datos.

  • Durability - Una vez que se ha completado una transacción, los resultados de esta transacción deben hacerse permanentes y no pueden borrarse de la base de datos debido a una falla del sistema.

Un sistema de base de datos RDBMS real garantizará las cuatro propiedades para cada transacción. La vista simplista de una transacción emitida a la base de datos usando SQL es la siguiente:

  • Comience la transacción usando el comando begin transaction .

  • Realice varias operaciones de eliminación, actualización o inserción mediante consultas SQL.

  • Si todas las operaciones son exitosas, realice la confirmación; de lo contrario, deshaga todas las operaciones.

Spring framework proporciona una capa abstracta sobre diferentes API de administración de transacciones subyacentes. El soporte de transacciones de Spring tiene como objetivo proporcionar una alternativa a las transacciones EJB agregando capacidades de transacción a los POJO. Spring admite la gestión de transacciones tanto programática como declarativa. Los EJB requieren un servidor de aplicaciones, pero la gestión de transacciones de Spring se puede implementar sin la necesidad de un servidor de aplicaciones.

Transacciones locales versus globales

Las transacciones locales son específicas de un único recurso transaccional como una conexión JDBC, mientras que las transacciones globales pueden abarcar múltiples recursos transaccionales como transacciones en un sistema distribuido.

La gestión de transacciones locales puede ser útil en un entorno informático centralizado donde los componentes y recursos de la aplicación se encuentran en un solo sitio, y la gestión de transacciones solo implica un administrador de datos local que se ejecuta en una sola máquina. Las transacciones locales son más fáciles de implementar.

La gestión de transacciones global es necesaria en un entorno informático distribuido donde todos los recursos se distribuyen en varios sistemas. En tal caso, la gestión de transacciones debe realizarse tanto a nivel local como global. Una transacción distribuida o global se ejecuta a través de múltiples sistemas, y su ejecución requiere la coordinación entre el sistema de gestión de transacciones global y todos los administradores de datos locales de todos los sistemas involucrados.

Programático frente a declarativo

Spring admite dos tipos de gestión de transacciones:

  • Gestión programática de transacciones : esto significa que debe gestionar la transacción con la ayuda de la programación. Eso le da una flexibilidad extrema, pero es difícil de mantener.

  • Gestión declarativa de transacciones : esto significa que separa la gestión de transacciones del código comercial. Solo usa anotaciones o configuración basada en XML para administrar las transacciones.

La gestión declarativa de transacciones es preferible a la gestión programática de transacciones, aunque es menos flexible que la gestión programática de transacciones, que le permite controlar las transacciones a través de su código. Pero como una especie de preocupación transversal, la gestión declarativa de transacciones se puede modularizar con el enfoque AOP. Spring admite la gestión de transacciones declarativas a través del marco Spring AOP.

Abstracciones de transacciones de primavera

La clave para la abstracción de la transacción Spring está definida por la interfaz org.springframework.transaction.PlatformTransactionManager , que es la siguiente:

public interface PlatformTransactionManager {
   TransactionStatus getTransaction(TransactionDefinition definition);
   throws TransactionException;
   
   void commit(TransactionStatus status) throws TransactionException;
   void rollback(TransactionStatus status) throws TransactionException;
}

No Señor Método y descripción
1

TransactionStatus getTransaction(TransactionDefinition definition)

Este método devuelve una transacción actualmente activa o crea una nueva, de acuerdo con el comportamiento de propagación especificado.

2

void commit(TransactionStatus status)

Este método confirma la transacción dada, con respecto a su estado.

3

void rollback(TransactionStatus status)

Este método realiza una reversión de la transacción dada.

El TransactionDefinition es la interfaz núcleo del soporte de transacciones en la primavera y se define de la siguiente manera -

public interface TransactionDefinition {
   int getPropagationBehavior();
   int getIsolationLevel();
   String getName();
   int getTimeout();
   boolean isReadOnly();
}

No Señor Método y descripción
1

int getPropagationBehavior()

Este método devuelve el comportamiento de propagación. Spring ofrece todas las opciones de propagación de transacciones familiares de EJB CMT.

2

int getIsolationLevel()

Este método devuelve el grado en que esta transacción está aislada del trabajo de otras transacciones.

3

String getName()

Este método devuelve el nombre de esta transacción.

4

int getTimeout()

Este método devuelve el tiempo en segundos en el que debe completarse la transacción.

5

boolean isReadOnly()

Este método devuelve si la transacción es de solo lectura.

A continuación se muestran los valores posibles para el nivel de aislamiento:

No Señor Aislamiento y descripción
1

TransactionDefinition.ISOLATION_DEFAULT

Este es el nivel de aislamiento predeterminado.

2

TransactionDefinition.ISOLATION_READ_COMMITTED

Indica que se evitan las lecturas sucias; pueden ocurrir lecturas no repetibles y lecturas fantasmas.

3

TransactionDefinition.ISOLATION_READ_UNCOMMITTED

Indica que pueden ocurrir lecturas sucias, lecturas no repetibles y lecturas fantasmas.

4

TransactionDefinition.ISOLATION_REPEATABLE_READ

Indica que se evitan las lecturas sucias y las lecturas no repetibles; pueden ocurrir lecturas fantasmas.

5

TransactionDefinition.ISOLATION_SERIALIZABLE

Indica que se evitan las lecturas sucias, las lecturas no repetibles y las lecturas fantasma.

A continuación se muestran los valores posibles para los tipos de propagación:

No Señor. Propagación y descripción
1

TransactionDefinition.PROPAGATION_MANDATORY

Admite una transacción actual; lanza una excepción si no existe una transacción actual.

2

TransactionDefinition.PROPAGATION_NESTED

Se ejecuta dentro de una transacción anidada si existe una transacción actual.

3

TransactionDefinition.PROPAGATION_NEVER

No admite una transacción actual; lanza una excepción si existe una transacción actual.

4

TransactionDefinition.PROPAGATION_NOT_SUPPORTED

No admite una transacción actual; en lugar de eso, siempre se ejecuta de forma no transaccional.

5

TransactionDefinition.PROPAGATION_REQUIRED

Admite una transacción actual; crea uno nuevo si no existe ninguno.

6

TransactionDefinition.PROPAGATION_REQUIRES_NEW

Crea una nueva transacción, suspendiendo la transacción actual si existe.

7

TransactionDefinition.PROPAGATION_SUPPORTS

Admite una transacción actual; se ejecuta de forma no transaccional si no existe ninguno.

8

TransactionDefinition.TIMEOUT_DEFAULT

Utiliza el tiempo de espera predeterminado del sistema de transacciones subyacente, o ninguno si no se admiten tiempos de espera.

La interfaz TransactionStatus proporciona una forma sencilla para que el código transaccional controle la ejecución de la transacción y consulte el estado de la transacción.

public interface TransactionStatus extends SavepointManager {
   boolean isNewTransaction();
   boolean hasSavepoint();
   void setRollbackOnly();
   boolean isRollbackOnly();
   boolean isCompleted();
}

No Señor. Método y descripción
1

boolean hasSavepoint()

Este método devuelve si esta transacción lleva internamente un punto de guardado, es decir, se ha creado como una transacción anidada basada en un punto de guardado.

2

boolean isCompleted()

Este método devuelve si esta transacción está completa, es decir, si ya se ha comprometido o revertido.

3

boolean isNewTransaction()

Este método devuelve verdadero en caso de que la transacción actual sea nueva.

4

boolean isRollbackOnly()

Este método devuelve si la transacción se ha marcado como solo de reversión.

5

void setRollbackOnly()

Este método establece la transacción como solo reversión.