Guía de primavera. Gestión de transacciones. Ejecutando el comando SELECT. Abstracciones de transacciones en primavera

El concepto de transacciones es una parte integral de cualquier base de datos cliente-servidor.

Una transacción se entiende como una secuencia indivisible de operadores de manipulación de datos (lectura, eliminación, inserción, modificación) desde el punto de vista del impacto en la base de datos, lo que lleva a uno de dos resultados posibles: o la secuencia se ejecuta en su totalidad si todos los operadores son correctos, o toda la transacción se revierte si al menos una declaración no se puede ejecutar con éxito. El procesamiento de transacciones garantiza la integridad de la información en la base de datos. Por tanto, una transacción mueve la base de datos de un estado consistente a otro.

Por ejemplo, considere una base de datos que gestiona cuentas bancarias. Supongamos que necesita transferir dinero de una cuenta a otra. Esto implica dos operaciones:

disminuir el saldo de la cuenta saliente;

aumentando el saldo de la cuenta receptora.

Si una de estas operaciones falla, la segunda también debe abortarse; de ​​lo contrario, la base de datos perderá integridad. Estas dos operaciones juntas constituyen una única transacción, que puede ejecutarse por completo o revertirse por completo.

La mayoría de las acciones realizadas se realizan en el cuerpo de la transacción. De forma predeterminada, cada comando se ejecuta como una transacción independiente. Si es necesario, el usuario puede especificar explícitamente su inicio y final para poder incluir varios comandos en él. Para hacer esto, use los siguientes comandos:

BEGIN TRAN: anuncio del inicio de una transacción (los valores iniciales de los datos que se cambian y el momento en que comenzó la transacción se registran en el registro de transacciones).

COMMIT TRAN: confirmar una transacción (si no hubo errores en el cuerpo de la transacción, este comando le indica al servidor que confirme todos los cambios realizados en la transacción, después de lo cual se anota en el registro de transacciones que los cambios se confirman y la transacción es terminado).

ROLLBACK TRAN: reversión de la transacción (cuando el servidor encuentra este comando, la transacción se revierte (se cancelan todos los cambios), se restaura condición original sistema y el registro de transacciones indica que la transacción fue revertida).

Considere el siguiente ejemplo.

Abra una nueva ventana de consulta y seleccione Ventas como base de datos activa

COMENZAR LA TRANSACCIÓN

Se iniciará la transacción. Cualquier modificación de los datos de esta conexión no será visible para otras conexiones.

Ingrese y ejecute la siguiente consulta

VALORES ("Ciudad Nueva")

Para verificar que la modificación fue exitosa ingrese y ejecute la siguiente consulta

apareció en la mesa nueva entrada, pero estos cambios son visibles sólo en este sentido

Abra una nueva ventana de consulta, ingrese y ejecute la consulta anterior en ella. La consulta no arrojará resultados porque está esperando a que se complete una transacción que se ejecuta en otra ventana.

Regrese a la primera ventana, ingrese y ejecute la siguiente consulta

TRANSACCIÓN DE ROLLBACK

Modificación de datos cancelada. Regrese a la segunda ventana. Tenga en cuenta que la solicitud se completó y devolvió datos. Falta la línea agregada.

La operación de realizar un nuevo pedido implica agregar nuevos registros a dos tablas a la vez: Order y OrdItem. Implementemos esta doble operación como una sola transacción:

INSERTAR(IdCust)

INSERTAR Artículo de pedido(IdOrd,IdProd,Cantidad,Precio)

VALORES(ALCANCE_IDENTIDAD(),1,1,5)

Cuando trabajamos con bases de datos (en adelante, bases de datos), generalmente necesitamos realizar una de 4 acciones: crear, leer, cambiar o eliminar (para este conjunto de acciones existe una abreviatura CRUD - Crear lectura Actualizar Eliminar). Si queremos realizar una de estas acciones, necesitamos realizar una transacción. Cuando hablamos de transacciones en el contexto de una base de datos, nos referimos a una secuencia de acciones con un número finito de operaciones para lograr un objetivo determinado, que se considera como un todo. En otras palabras, si una de las operaciones de una secuencia falla, entonces se considera que toda la secuencia ha fallado. La gestión de transacciones es una parte importante de cualquier sistema de gestión de bases de datos (en adelante, DBMS), garantiza la integridad y la falta de ambigüedad de los datos.

Los conceptos básicos de una transacción se describen con el acrónimo ACID: Atomicidad, Consistencia, Aislamiento, Durabilidad.

Atomicidad

La atomicidad garantiza que cualquier transacción se realizará únicamente en su totalidad. Si una de las operaciones de la secuencia falla, se revertirá toda la transacción. Aquí se introduce el concepto de "reversión". Aquellos. Ciertos cambios ocurrirán dentro de la secuencia, pero al final todos serán cancelados (“revertidos”) y como resultado el usuario no verá ningún cambio.

Consistencia

Esto significa que cualquier transacción completada (una transacción que ha llegado al final de la transacción) solo registra resultados válidos. Por ejemplo, al transferir dinero de una cuenta a otra, si el dinero sale de una cuenta, debe llegar a otra (esta es la coherencia del sistema). El débito y el abono son dos transacciones diferentes, por lo que la primera transacción se realizará sin errores, pero la segunda simplemente no. Por eso es sumamente importante tener en cuenta esta propiedad y mantener el equilibrio del sistema.

Aislamiento

Cada transacción debe estar aislada de las demás, es decir. su resultado no debe depender de la ejecución de otras transacciones paralelas. En la práctica, el aislamiento es algo extremadamente difícil de lograr, por lo que aquí se introduce el concepto de "niveles de aislamiento" (la transacción no está completamente aislada).

Durabilidad

Este concepto garantiza que si recibimos confirmación de que una transacción se ha completado, los cambios causados ​​por esa transacción no se deben deshacer debido a una falla del sistema (como un corte de energía).

EN vida real Cualquier DBMS de calidad admite todos estos 4 conceptos para cada transacción. Si consideramos la transacción de forma simplificada, entonces la transacción (cuando se trabaja con SQL) se parece a esto:

  • El usuario inicia una transacción usando el comando “iniciar transacción”;
  • Los sistemas realizan una operación de creación, cambio o eliminación mediante una consulta SQL;
  • Si todas las operaciones tienen éxito, se realiza la operación de confirmación. Si hay un error, todas las operaciones se revierten (revertir);

Para varias API de gestión de transacciones, Spring admite una capa abstracta. Spring agrega capacidad de transacción para POJO (objetos Java antiguos y simples).

Tipos de gestión de transacciones en Spring

admite 2 tipos de gestión de transacciones:

Una forma de gestionar transacciones mediante programación. Este método es más complejo de leer y mantener que el método declarativo, pero proporciona mayor flexibilidad.

Con la gestión de transacciones declarativa, separamos la lógica empresarial de la gestión de transacciones. Usamos anotaciones o un archivo XML para la configuración de la gestión de transacciones.

En la práctica, el método declarativo de gestión de transacciones se utiliza con mayor frecuencia. Aunque este método es menos flexible que el software, puede ser modular (como AOP). Vale la pena señalar que el método declarativo se implementa mediante el módulo AOP.

Spring es una alternativa a EJB, que requiere un servidor para ejecutar la aplicación, mientras que la gestión de transacciones en Spring se puede implementar sin un servidor de aplicaciones.

Abstracciones de transacciones en primavera

Las principales abstracciones de transacciones en Spring se definen en la interfaz. Administrador de transacciones de plataforma, que está en el paquete org.springframework.transaction.

Contiene 3 métodos:

TransactionStatus getTransaction(definición de TransactionDefinition);

Este método devuelve la transacción actualmente activa o crea una nueva según lo definido.

confirmación nula (estado de estado de transacción);

Este método ejecuta la transacción según su estado.

reversión nula (estado de estado de transacción);

Este método revierte una transacción. .

Interfaz TransactionDefinition incluye 5 métodos

int getPropagationBehavior()

Devuelve el método de propagación.

int getIsolationLevel()

Devuelve el nivel de aislamiento.

Cadena getName()

Devuelve el nombre de la transacción.

int getTimeout()

Devuelve el tiempo en segundos dentro del cual se debe completar la transacción.

booleano esReadOnly()

El método devuelve un valor booleano (verdadero o falso) que indica si el archivo es de solo lectura.

Y nuestro último interfaz clave Estado de la transacción, que proporciona una manera sencilla de monitorear el estado de ejecución de una transacción. Define los siguientes métodos:

booleano tieneSavepoint()
Este método devuelve un valor booleano si la transacción dada tiene un punto de guardado.

booleano está completado()

Devuelve un valor booleano si esta transacción se completa (se completa con éxito o se revierte).

booleano esNuevaTransacción()

Devuelve un valor booleano si la transacción actual es nueva.

booleano esRollbackOnly()

Devuelve un valor booleano si esta transacción se marcó como de solo reversión.

conjunto vacíoRollbackOnly()

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

En este artículo, aprendimos los conceptos básicos de la gestión de transacciones en Spring Framework.

Transacción- Esta es una secuencia indivisible, desde el punto de vista del impacto en el DBMS, de operaciones de manipulación de datos. Para el usuario, la transacción se realiza según el principio " todo o nada", es decir. o la transacción se ejecuta en su totalidad y transfiere la base de datos de un estado holístico a otro estado holístico o, si por alguna razón una de las acciones de la transacción no es ejecutable, o se ha producido algún mal funcionamiento del sistema, la base de datos vuelve a su estado original que tenía antes del inicio de la transacción (la transacción se revierte). Desde este punto de vista, las transacciones son importantes tanto en sistemas multiusuario como en sistemas monousuario. En los sistemas de usuario único, las transacciones son unidades lógicas de trabajo, después de las cuales la base de datos permanece en perfecto estado. Las transacciones también son unidades de recuperación datos después de fallas: durante la recuperación, el sistema elimina los rastros de transacciones que no tuvieron tiempo de completarse con éxito como resultado de una falla de software o hardware. Estas dos propiedades de las transacciones determinan la atomicidad (indivisibilidad) de una transacción. En los sistemas multiusuario, además, las transacciones sirven para garantizar aislado trabajo de usuarios individuales: los usuarios que trabajan simultáneamente con una base de datos parecen trabajar como si estuvieran en un sistema de un solo usuario y no interfieren entre sí.

Transacción o unidad lógica de operación de la base de datos, está en caso general una secuencia de una serie de operaciones que transforman algún estado consistente de la base de datos en otro estado consistente, pero no garantizan que la coherencia se mantendrá en todos los puntos intermedios en el tiempo.

Una transacción tiene cuatro propiedades importantes conocidas como Propiedades ASID :

  • (A) Atomicidad. Una transacción se ejecuta como una operación atómica: o se ejecuta toda la transacción o no se ejecuta toda la transacción.
  • (CON) Consistencia. Una transacción mueve la base de datos de un estado consistente (integral) a otro estado consistente (integral). Dentro de una transacción, la coherencia de la base de datos puede fallar.
  • (Y) Aislamiento. Actas diferentes usuarios no deben interferir entre sí (por ejemplo, como si se ejecutaran estrictamente por turnos).
  • (D) Durabilidad. Si se completa una transacción, los resultados de su trabajo deben guardarse en la base de datos, incluso si la siguiente el momento sucederá fallo del sistema.

La transacción generalmente comienza automáticamente cuando el usuario se une al DBMS y continúa hasta que ocurre uno de los siguientes eventos:

  • se emitió el comando COMMIT (confirmar la transacción);
  • se emitió el comando ROLLBACK (revertir la transacción);
  • el usuario ha sido desconectado del DBMS;
  • ocurrió una falla en el sistema.

Las propiedades de las transacciones ASID no siempre se implementan por completo. Esto se aplica especialmente a la propiedad. Y(aislamiento). Idealmente, las transacciones de diferentes usuarios no deberían interferir entre sí, es decir. deben realizarse de tal manera que el usuario tenga la ilusión de que está solo en el sistema. La forma más sencilla Garantizar un aislamiento absoluto consiste en poner en cola las transacciones y ejecutarlas estrictamente una tras otra. Evidentemente, se pierde la eficiencia del sistema. Por tanto, en realidad se ejecutan varias transacciones simultáneamente ( mezcla de transacciones). Hay varios niveles de aislamiento de transacciones. En nivel más bajo Las transacciones de aislamiento en realidad pueden interferir entre sí, en el nivel más alto: están completamente aisladas. Un mayor aislamiento de las transacciones tiene el costo de una mayor sobrecarga del sistema y un rendimiento más lento. Los usuarios o el administrador del sistema pueden, a su discreción, configurar diferentes niveles Aislamiento de todas o transacciones individuales. El aislamiento de transacciones se analiza con más detalle en la sección 4.6.3.


Propiedad D(durabilidad) tampoco es una propiedad absoluta, porque Algunos sistemas permiten transacciones anidadas. Si la transacción B se ejecuta dentro de la transacción A y se emite un comando COMMIT para la transacción B, entonces la confirmación de los datos de la transacción B es condicional, porque La transacción externa A se puede revertir. Los resultados de la transacción interna B se confirmarán finalmente solo si se confirma la transacción externa A.

Propiedad ( CON)- La coherencia de las transacciones está determinada por la presencia del concepto de coherencia de la base de datos. La base de datos se encuentra en estado consistente (integral), si se cumplen (satisfechas) todas las restricciones de integridad definidas para la base de datos.

Restricción de integridad(regla de negocio) es una declaración que puede ser verdadera o falsa según el estado de la base de datos.

Ejemplos de restricciones de integridad incluyen las siguientes declaraciones:

Ejemplo 4.62. Cada cliente tiene un solo vendedor.

Ejemplo 4.63 . Cada empleado tiene un número de personal único.

Ejemplo 4.64 Un empleado debe estar registrado en un solo departamento.

Ejemplo 4.65 . La cantidad de dinero en la factura debe ser igual a la suma de los productos de los precios de los bienes y la cantidad de bienes para todos los bienes incluidos en la factura.

Como puede ver en estos ejemplos, algunas de las restricciones de integridad son restricciones modelo relacional datos (ver Capítulo 3). El ejemplo 4.63 representa una restricción que implementa la integridad de la entidad. Los ejemplos 4.62, 4.64 representan restricciones que implementan la integridad referencial. Otras restricciones son declaraciones bastante arbitrarias, declaraciones relacionadas con las reglas de un determinado área temática(Ejemplo 4.65). Cualquier restricción de integridad es semántico concepto, es decir aparece como consecuencia de ciertas propiedades de los objetos en el área temática y/o sus relaciones.

Junto con el concepto de integridad de la base de datos viene el concepto Reacción del sistema ante un intento de violar la integridad. . El sistema no sólo debe verificar si se violan las restricciones durante diversas operaciones, sino también responder adecuadamente si una operación resulta en una violación de la integridad. Hay dos tipos de respuesta ante un intento de violar la integridad:

  1. Negativa realizar una operación "ilegal".
  2. Ejecución compensando comportamiento.

El funcionamiento del sistema para verificar restricciones se muestra en la Figura 4.1.

Cada sistema tiene sus propios medios para soportar las restricciones de integridad. Las restricciones de integridad se clasifican de varias maneras:

  • por métodos de implementación;
  • por hora de verificación;
  • por alcance.

Según los métodos de implementación, se distinguen:

  • soporte declarativo para restricciones de integridad: utilizando lenguaje de definición de datos (DDL);
  • procesal soporte para restricciones de integridad, a través de activadores y procedimientos almacenados.

Figura 4.1 Operación del sistema para verificar restricciones

Según el tiempo de verificación, las restricciones se dividen en:

  • restricciones inmediatamente comprobables;
  • restricciones de cheques diferidos.

Por alcance, las restricciones se dividen en:

  • restricciones de dominio;
  • restricciones de atributos;
  • restricciones de tupla;
  • restricciones de relación;
  • limitaciones de la base de datos.

El estándar del lenguaje SQL sólo admite restricciones declarativas integridad, implementado como:

  • restricciones de dominio;
  • restricciones incluidas en la definición de la tabla;
  • restricciones almacenadas en la base de datos como afirmaciones independientes.

La verificación de restricciones está permitida tanto después de la ejecución de cada declaración que podría violar la restricción como al final de la transacción. Mientras se ejecuta una transacción, puede cambiar el modo de verificación de restricciones.

estándar SQL no proporciona Restricciones de integridad procesal implementadas mediante activadores y procedimientos almacenados. El estándar SQL 92 no contiene el concepto de "disparador", aunque los desencadenadores están disponibles en todos los DBMS industriales de tipo SQL. Por lo tanto, la implementación de restricciones utilizando los medios de un DBMS específico tiene mayor flexibilidad que usar exclusivamente medios estándar SQL.

Transacción es una secuencia de operaciones en una base de datos considerada por el DBMS como un todo. Si todas las operaciones se completan exitosamente, entonces la transacción también se considera exitosa y el DBMS arreglos(COMMIT) todos los cambios de datos realizados por esta transacción (es decir, escribe los cambios en la memoria externa). Si falla al menos una operación de transacción, entonces la transacción se considera fallida y se realiza una reversión (ROLLBACK), cancelando todos los cambios de datos realizados durante la transacción y devolviendo la base de datos al estado anterior a que comenzara la transacción. La gestión de transacciones es necesaria para mantener la integridad lógica de la base de datos. La compatibilidad con el mecanismo de transacción es un requisito previo incluso para los DBMS de un solo usuario, y más aún para los DBMS multiusuario. La propiedad de que cada transacción comienza con un estado intacto de la base de datos y deja este estado intacto después de su finalización hace que sea muy conveniente utilizar el concepto de transacción como una unidad de actividad del usuario en relación con la base de datos. Con una gestión adecuada de las transacciones concurrentes por parte del DBMS, cada usuario puede, en principio, sentirse como el único usuario del DBMS.

Asociados con la gestión de transacciones en un DBMS multiusuario están los conceptos importantes de serialización de transacciones y un plan en serie para ejecutar una combinación de transacciones. Por serialización de transacciones en ejecución paralela nos referimos a planificar su trabajo de tal manera que el resultado total de una combinación de transacciones sea equivalente al resultado de su ejecución secuencial. Un plan en serie para ejecutar una combinación de transacciones es aquel que da como resultado la serialización de transacciones. Está claro que si es posible lograr una ejecución verdaderamente en serie de una combinación de transacciones, entonces para cada usuario por cuya iniciativa se formó la transacción, la presencia de otras transacciones será invisible (excepto por alguna desaceleración en la operación en comparación con la única). -modo usuario).

Existen varios algoritmos básicos de serialización de transacciones. En los DBMS centralizados, los algoritmos más comunes son los basados ​​en adquisiciones sincronizadas de objetos de bases de datos. Cuando se utiliza cualquier algoritmo de serialización, es posible que se produzcan conflictos entre múltiples transacciones que acceden a objetos de la base de datos. En este caso, se deben revertir una o más transacciones para mantener la serialización. Este es uno de los casos en los que un usuario de un DBMS multiusuario puede sentir (y de manera bastante desagradable) la presencia de transacciones de otros usuarios en el sistema.

Llevar un diario

Uno de los principales requisitos para un DBMS es la confiabilidad del almacenamiento de datos en memoria externa. La confiabilidad del almacenamiento significa que el DBMS debe poder restaurar el último estado consistente de la base de datos después de cualquier falla de hardware o software. Los fallos de hardware suelen dividirse en dos tipos:

    Los fallos leves implican que una computadora se detiene repentinamente.

    Por lo general, son consecuencia de un corte repentino de energía o de una congelación del sistema operativo (lo cual es especialmente típico de los sistemas operativos Windows);

Los fallos graves se caracterizan por la pérdida de información en medios de memoria externos. Los fallos del software suelen producirse debido a errores en los programas. Además, estos errores pueden estar en el propio DBMS, lo que puede provocar chocar su trabajo y en programa de usuario

. El primer caso puede considerarse un tipo de falla de hardware de software. En el segundo caso, sólo una transacción queda incompleta. En cualquier caso, para restaurar información en la base de datos, es necesario tener alguna información adicional. Por lo tanto, se requiere redundancia de datos para mantener la confiabilidad del almacenamiento de datos. Además, la parte de la información que se utiliza para la recuperación debe almacenarse de forma especialmente segura. El método más común para mantener dicha información redundante es mantener un registro de cambios en la base de datos. El registro es una parte especial de la base de datos, inaccesible para los usuarios del DBMS y se mantiene con especial cuidado (a veces se utilizan dos copias del registro, ubicadas en diferentes discos fisicos ), que recibe registros de todos los cambios en la parte principal de la base de datos. En diferentes DBMS, los cambios en la base de datos se registran: A veces una entrada de registro corresponde a alguna operación lógica de modificación de la base de datos, a veces a una operación mínima de modificación interna de una página de memoria externa. Ambos enfoques también se pueden utilizar simultáneamente. En todos los casos, se sigue la estrategia de registro “proactivo” (el llamado protocolo Write Ahead Log - WAL). De manera algo exagerada, podemos decir que esta estrategia consiste en que se debe registrar un registro de un cambio en cualquier objeto de la base de datos antes de ejecutar y registrar el cambio en este objeto. Si el DBMS sigue correctamente el protocolo WAL, entonces, utilizando el registro, puede resolver todos los problemas de recuperación de la base de datos después de cualquier falla.

La situación de recuperación más simple es la reversión de una transacción individual. Estrictamente hablando, esto no requiere un registro de cambios en la base de datos de todo el sistema. Es suficiente para cada transacción mantener un registro local de las operaciones de modificación de la base de datos realizadas en esta transacción y revertir la transacción realizando operaciones inversas, siguiendo "desde el final del registro local". Algunos DBMS hacen esto, pero la mayoría de los sistemas lo hacen. no admite registros locales, y la reversión de transacciones individuales se realiza utilizando el registro de todo el sistema, para el cual todos los registros relacionados con una transacción están vinculados en una lista inversa (de principio a fin, en caso de una falla suave, la memoria externa). de la parte principal de la base de datos puede contener objetos modificados por transacciones que no se completaron en el momento del fallo, y puede que no haya objetos modificados por transacciones que se completaron con éxito en el momento del fallo (debido al uso de RAM). buffers, cuyo contenido se pierde durante una falla suave). Si se sigue el protocolo WAL, se debe garantizar que la memoria de registro externa contenga registros relacionados con operaciones de modificación de ambos tipos. El objetivo del proceso de recuperación de fallas leves es llevar la memoria externa de la parte principal de la base de datos a un estado que ocurriría si los cambios de todas las transacciones completadas se enviaran a la memoria externa y que no contuviera ningún rastro de transacciones pendientes. Para lograr esto, primero revierten las transacciones incompletas y luego reproducen aquellas operaciones de transacciones completadas cuyos resultados no se muestran en la memoria externa.

Para recuperar una base de datos después de un fallo grave, utilice un registro y una copia archivada de la base de datos. Una copia de archivo es copia completa base de datos en el momento en que el registro comienza a llenarse (aunque hay muchas opciones para interpretar el significado copia de archivo). Para recuperar correctamente una base de datos después de un fallo grave, por supuesto, es necesario que no se pierda el registro. Luego, la recuperación de la base de datos consiste en reproducir, a partir de la copia del archivo, el trabajo de todas las transacciones que finalizaron en el momento del fallo utilizando el registro. En principio, incluso es posible reproducir transacciones pendientes y continuar con su operación una vez completada la recuperación. Sin embargo, en sistemas reales esto generalmente no se hace, ya que el proceso de recuperación después de una falla grave es bastante largo.

El concepto de transacción está en el centro del paradigma relacional. Una transacción consta de uno o más comandos DML y siguiente comando o ROLLBACK o COMMIT. Es posible utilizar el comando SAVEPOINT para cierta gestión dentro de una transacción. Antes de analizar la sintaxis, es necesario revisar el concepto de transacciones. Relacionado con este tema está el tema de la lectura constante; Esto se implementa automáticamente en el nivel del servidor Oracle, pero algunos programadores pueden controlarlo usando comandos SELECT.

El mecanismo de Oracle para garantizar la integridad transaccional se basa en una combinación de segmentos de deshacer y un archivo de registro: este mecanismo es sin duda el mejor creado hasta la fecha y satisface completamente estándares internacionales proceso de datos. Los fabricantes de otras bases de datos implementan el estándar a su manera. En resumen, cualquier base relacional los datos deben satisfacer la prueba ACID: se deben garantizar la atomicidad (A - atomicidad), la consistencia (C - consistencia), el aislamiento (I - aislamiento) y la durabilidad (D - durabilidad).

Atomalidad

El principio de atomicidad establece que todas las partes de una transacción deben tener éxito o ninguna de ellas. Por ejemplo, si un analista de negocios aprobó la regla de que cuando cambia el salario de un empleado, el nivel del empleado necesariamente cambia, entonces su transacción atómica constará de dos partes. La base de datos debe garantizar que se apliquen ambos cambios o ninguno. Si solo un cambio tiene éxito, tendrás un empleado cuyo salario es incompatible con su nivel: corrupción de datos en términos comerciales. Si algo (cualquier cosa) sale mal antes de que se confirme la transacción, la base de datos debe garantizar que todo el trabajo realizado hasta ese momento desde el inicio de la transacción se deshaga: esto debería funcionar automáticamente. Aunque la atomicidad de las transacciones parezca algo pequeño, las transacciones pueden ser largas y muy importantes. Consideremos otro ejemplo, en el libro mayor no puede haber datos de medio mes de agosto y medio mes de septiembre: cerrar un mes desde un punto de vista empresarial es una transacción atómica que puede procesar millones de filas y miles de tablas y trabajar. durante varias horas (o cancelarse si sucede algo que salió mal). Una transacción se puede cancelar manualmente (emitiendo el comando ROLLBACK), pero debe ser automática y no cancelable en caso de error.

Consistencia

El principio de coherencia de los datos establece que el resultado de una consulta debe ser coherente con el estado de la base de datos en el momento en que se inicia la consulta. Imaginemos una consulta sencilla que calcula el valor medio de una columna de una tabla. Si la mesa es grande, esto llevará bastante tiempo. por mucho tiempo para recorrer todas las filas de la tabla. Si otros usuarios están actualizando datos mientras se ejecuta la consulta, ¿la consulta debería tomar los valores nuevos o los antiguos? ¿El resultado de la consulta debería tener en cuenta las filas que se agregaron o ignorar las filas que se eliminaron? El principio de coherencia requiere que la base de datos garantice que cualquier cambio después del inicio de una consulta no sea visible para esa consulta; la consulta debe devolver el valor promedio de la columna en el momento en que se ejecutó la consulta, independientemente de cuánto duró la consulta o qué cambios se realizaron en los datos. Oracle garantiza que si la solicitud se completa con éxito, el resultado será consistente. Sin embargo, si el administrador de la base de datos no ha configurado la base de datos adecuadamente, la consulta puede fallar con el famoso error "Instantánea ORA-1555 demasiado antigua". Antes era muy difícil solucionar este tipo de errores, pero en últimas versiones el administrador puede manejar fácilmente estas situaciones.

Aislamiento

El principio de aislamiento establece que una transacción inconclusa (no confirmada) debería ser invisible para el resto del mundo. Mientras una transacción está en progreso, solo la sesión que realiza esta transacción ve los cambios. Todas las demás sesiones deberían ver datos sin cambios. ¿Por qué es así? En primer lugar, es posible que toda la transacción no se complete por completo (recuerde el principio de atomicidad y coherencia) y, por lo tanto, nadie debería ver cambios que puedan cancelarse. En segundo lugar, durante la transacción, los datos (en términos comerciales) son incoherentes: para nuestro ejemplo de actualización del salario, habrá un período de tiempo en el que el salario habrá cambiado, pero el nivel aún no se ha alcanzado. El aislamiento de transacciones requiere que la base de datos oculte las transacciones actuales a otros usuarios: verán los datos antes de los cambios mientras la transacción está en progreso, y luego verán inmediatamente todos los cambios como un conjunto consistente de datos. Oracle garantiza el aislamiento de las transacciones: no hay forma de que una sesión (que no sea la que realiza los cambios) vea datos no confirmados. Oracle no permite la lectura de datos no confirmados (conocido como lectura sucia) (aunque algunas otras bases de datos sí lo hacen).

Durabilidad

El principio de durabilidad establece que si una transacción se completa con éxito, entonces debería ser imposible perder esos datos. Durante una transacción, el principio de aislamiento requiere que nadie, excepto la sesión que realiza los cambios, los vea. Pero una vez que una transacción se ha completado con éxito, los cambios deben estar disponibles para todos y la base de datos debe garantizar que no se pierdan. Oracle cumple con este requisito escribiendo todos los vectores de cambios en archivos de registro antes de que se confirmen los cambios. Aplicar este registro de cambios a copias de seguridad, siempre es posible repetir cualquier cambio que se haya realizado cuando la base de datos se detuvo o se dañó. Por supuesto, los datos se pueden perder debido a errores del usuario, como ejecutar consultas DML no válidas o eliminar tablas. Pero desde el punto de vista de Oracle y del DBA, estos eventos también son transacciones: según el principio de durabilidad, no se pueden deshacer.

Ejecutar SQLsolicitudes

Todo lenguaje SQL Está formado por una docena de equipos. Ahora nos interesan los comandos: SELECCIONAR, INSERTAR, ACTUALIZAR y ELIMINAR.

Ejecutando el comando SELECT

El comando SELECT recibe datos. La ejecución de un comando SELECT es un proceso de varios pasos: el proceso del servidor que ejecuta la consulta comprobará si bloques requeridos datos en la memoria, en el buffer de caché. Si están allí, entonces la ejecución puede continuar; de lo contrario, el proceso del servidor debe encontrar los datos en el disco y copiarlos al búfer de caché.

Recuerde siempre que los procesos del servidor leen bloques de archivos de datos en el caché del búfer de la base de datos, DBWn escribe bloques desde el caché del búfer de la base de datos en los archivos de datos.

Cuando los bloques con los datos necesarios para completar la solicitud están en el buffer de caché, cualquier procesos adicionales(como la clasificación y la agregación) continúan en la sesión de la PGA. Cuando se completa la ejecución, el resultado se devuelve al proceso del usuario.

¿Cómo se relaciona esto con la prueba ACID? Para mantener la coherencia, si una solicitud detecta que un bloque de datos ha cambiado desde que se inició la solicitud, el proceso del servidor encontrará un segmento de reversión (o segmento de deshacer) correspondiente a este cambio, buscará la versión anterior de los datos y (para el solicitud actual) deshaga el cambio. Por lo tanto, los cambios que ocurrieron después del inicio de la solicitud no serán visibles. De manera similar, el aislamiento de las transacciones está garantizado, aunque el aislamiento también se basa en cambios confirmados. Francamente, si los datos necesarios para deshacer los cambios ya no existen en el segmento de reversión, este mecanismo no funcionará. De aquí proviene el error "instantánea demasiado antigua".

La Figura 8-4 muestra la ruta de procesamiento para una consulta SELECT.

El paso 1 consiste en pasar la solicitud del usuario del proceso del usuario al proceso del servidor. El proceso del servidor escanea el búfer de caché en busca de los bloques necesarios y, si están en el búfer, continúa con el paso 4. De lo contrario, el paso 2 busca los bloques en los archivos de datos y el paso 3 copia los datos al búfer. El paso 4 pasa los datos al proceso del servidor donde pueden estar procesamiento adicional antes del paso 5 devuelve el resultado de la consulta al proceso del usuario.

Ejecutando el comando ACTUALIZAR

Para cualquier comando DML, es necesario trabajar con bloques de datos y bloques de deshacer, así como crear un registro de cambios (rehacer): los principios A, C e I de la prueba ACIDS requieren la creación de datos de deshacer; D requiere la creación de datos de rehacer.

¡Deshacer no es lo opuesto a rehacer! Rehacer protege todos los cambios de bloque, independientemente de si son cambios en un bloque de tabla, índice o segmento de reversión. Para rehacer y deshacer, el segmento es el mismo segmento que las tablas y todos los cambios deben ser duraderos.

El primer paso al ejecutar un comando DML es el mismo que al ejecutar un comando SELECT: los bloques necesarios deben encontrarse en el búfer cef o copiarse de los archivos de datos al búfer. La única diferencia es que se requiere un bloque de reversión vacío (o caducado) adicional. Entonces la ejecución se vuelve más complicada que con el comando SELECT.

Primero, se deben especificar bloqueos para todas las filas y los índices correspondientes que participarán en el proceso.

Luego se crean los datos de rehacer: el proceso del servidor escribe en los registros del búfer el vector de cambios que se aplicará a los datos. Los datos de rehacer se crean tanto para cambios de bloques de datos como para cambios de bloques de reversión: si se actualiza una columna en una fila, entonces el ID de fila y el nuevo valor se escriben en el búfer de registro (el cambio que se aplicará al bloque de tabla), también como el valor anterior de la columna (el cambio para el bloque de reversión). Si la columna es parte de una clave de índice, los cambios en el índice también se escribirán en el búfer de registro, junto con los cambios que se realizarán en el bloque de reversión para proteger los cambios del índice.

Después de que se hayan creado todos los datos de rehacer, los datos en el búfer de caché se actualizan: el bloque de datos se actualiza a nueva versión con una columna modificada, y versión antigua se escribe en el bloque de deshacer. Desde este momento hasta que se confirme la transacción, todas las solicitudes de otras sesiones que accedan a esta línea serán redirigidas al bloque de reversión. Sólo verá la sesión que haga la ACTUALIZACIÓN versión actual filas en un bloque de tabla. El mismo principio se aplica a todos los índices relacionados.

Ejecutar comandos INSERTy BORRAR

Conceptualmente, INSERTAR y ELIMINAR se manejan de la misma manera que ACTUALIZAR. Primero, se buscan en el búfer los bloques necesarios y, si no están allí, se copian en la memoria.

Rehacer se crea de la misma manera: todos los vectores de cambio que se aplicarán a los datos y los bloques de reversión se escriben primero en el búfer de registro. Para un comando INSERT, el vector de cambios en un bloque de tabla (y posiblemente en bloques de índice) son los bytes que componen la nueva fila (y posiblemente nueva claveíndice). El vector para el bloque de reversión es rowid nueva linea. Para un comando ELIMINAR, el vector del bloque deshacer es la línea completa.

La diferencia clave entre los comandos INSERT y UPDATE es la cantidad de datos que se van a revertir. Cuando se agrega una fila, los únicos datos que se revertirán serán la entrada del ID de fila en el bloque de reversión, porque para deshacer un comando INSERT, la única información que Oracle necesita es el ID de fila de la fila y se puede crear el comando.

eliminar de table_name donde rowid=rowd_id_of_new_row;

Ejecutar este comando deshará el cambio.

Para un comando DELETE, se debe escribir toda la fila (que puede tener varios kilobytes) en un bloque de deshacer, y luego la eliminación se puede deshacer si es necesario generando una consulta que vuelva a agregar la fila completa a la tabla.

Inicio y fin de la transacción

Una sesión comienza una transacción en el momento en que ejecuta cualquier comando DML. La transacción continúa para tantos comandos DML como sea posible hasta que la sesión emita un comando ROLLBACK o COMMIT. Sólo se garantizarán los cambios confirmados y estarán disponibles para otras sesiones. No es posible iniciar una transacción dentro de una transacción. El estándar SQL no permite a los usuarios iniciar una transacción y luego iniciar una nueva antes de completar la primera. Esto se puede hacer usando PL/SQL (el lenguaje Oracle de tercera generación), pero no SQL estándar.

Los comandos de control de transacciones son COMMIT, ROLLBACK y SAVEPOINT. También puede haber circunstancias distintas a la llamada explícita a COMMIT o ROLLBACK que finalicen inmediatamente la transacción.

  • Ejecutar un comando DDL o DCL
  • Finalizar un proceso de usuario (por ejemplo, el usuario ha salido de SQL *Plus o SQL Developer)
  • La sesión del cliente "murió"
  • Problemas en el sistema.

Si el usuario emite un comando DDL (CREATE, ALTER o DROP) o un comando DCL (GRANT o REVOKE), entonces se confirmará la transacción activa (si existe). Esto sucede porque los comandos DDL y DCL son en sí mismos transacciones. Dado que no es posible crear transacciones anidadas en SQL, si el usuario ya tiene una transacción en curso, todos los comandos del usuario se confirmarán junto con el comando DDL o DCL.

Si inició una transacción ejecutando Solicitar DML y luego cerró el programa sin indicación explícita COMMIT o ROLLBACK antes de salir, la transacción se cancelará, pero si se cancela o se cancela depende completamente del programa. Ud. diferentes programas Puede haber un comportamiento diferente dependiendo de cómo terminó de trabajar en el programa. Por ejemplo, en Windows normalmente puede salir del programa seleccionando el elemento de menú Archivo – Salir o haciendo clic en la cruz de la derecha. esquina superior. El programador podría procesar estos métodos de finalización de manera diferente y en el primer caso indicar COMMIT, y en el segundo ROLLBACK. En cualquier caso, será una salida controlada.

Si la sesión de un cliente falla por algún motivo, la base de datos siempre abortará la transacción. Tales fallas pueden ser varias razones: el proceso del usuario podría ser "eliminado" por el despachador, problemas de red o la máquina del usuario podría fallar. En cualquier caso, el comando COMMIT o ROLLBACK no se especificó explícitamente y la base de datos necesita decidir qué sucedió. En este caso, la sesión se "cierra" y la transacción activa se cancela. Y la base de datos se comporta exactamente de la misma manera en caso de problemas en el lado del servidor. Si la base de datos se cerró de forma anormal, en el siguiente inicio se cancelarán todas las transacciones que se iniciaron pero que no se completaron claramente.

Controltransacciones: COMMIT, ROLLBACK, SAVEPOINTy SELECCIONAR PARA ACTUALIZAR

Oracle comienza una transacción en el momento en que se emite el primer comando DML. La transacción dura hasta que se llama al comando ROLLBACK o COMMIT. El comando SAVEPOINT no forma parte de estándar SQL y en realidad es la manera fácil para que el programador deshaga los cambios parcialmente en orden inverso.

El comando COMMIT es donde muchas personas (e incluso algunos DBA) muestran confusión arquitectura oracle. Cuando emite un COMMIT, todo lo que sucede físicamente es que LGWR escribe el búfer de registro en el disco. DBWn no hace absolutamente nada. Este es uno de los más propiedades importantes Oráculo para lograr rendimiento alto DB.

¿Qué hace DBWn cuando se ejecuta un comando COMMIT? Respuesta: absolutamente nada

Para que una transacción sea duradera, todo lo que necesita hacer es escribir los cambios que se realizaron durante la transacción en el disco: no hay necesidad de datos reales en el disco. Si los cambios se registran en forma de muchas copias de los registros de cambios en el disco, incluso si la base de datos está dañada, todas las transacciones se pueden repetir restaurando una copia de seguridad de los datos antes del error y aplicando los cambios de los registros. En en este momento debe comprender el hecho de que COMMIT simplemente borra el búfer de registro en el disco y marca la transacción como completada. Por este motivo, las transacciones que implican millones de actualizaciones de miles de archivos durante varias horas pueden confirmarse en una fracción de segundo. Dado que LGWR registra los registros casi en tiempo real, prácticamente todos los cambios de transacciones ya están escritos en el disco. Cuando emite un COMMIT, LGWR escribe inmediatamente el registro en el disco: su sesión esperará hasta que finalice la grabación. El tiempo de retraso será igual al tiempo que lleva escribir los datos más recientes del búfer de registro, lo que suele tardar unos milisegundos. Luego, su sesión puede continuar ejecutándose y todas las demás sesiones no serán redirigidas a los datos en el segmento de reversión cuando acceda a datos actualizados, a menos que la coherencia lo requiera. Los vectores de cambio escritos en el registro de rehacer cambios son todos cambios: los que se aplican tanto a los bloques de datos (tablas e índices) como a los bloques de reversión.

El registro de rehacer incluye todos los cambios: se aplica a los segmentos de datos y a los segmentos de deshacer para transacciones confirmadas y no confirmadas.

Lo más incomprensible es que rehacer se escribe en archivos LGWR y contendrá tanto confirmado como transacciones no confirmadas. Aún más, en cualquier momento, DBWn puede o no escribir segmentos de datos modificados o bloques de segmentos de reversión en los archivos de datos para transacciones confirmadas y no confirmadas. Es decir, su base de datos en el disco es inconsistente: los archivos de datos pueden almacenar datos de transacciones no confirmadas y pueden no contener cambios confirmados. Pero en cualquier momento, en caso de un problema, hay suficiente información en el archivo de registro en el disco para repetir las transacciones confirmadas que faltan en los archivos de datos (usando cambios en los bloques de datos) y restaurar los segmentos de reversión (usando cambios en bloques de reversión) necesarios para cancelar todas las transacciones no confirmadas que se registran en archivos de datos.

Cualquier comando DDL, así como GRANT o REVOKE confirmarán la transacción actual

RETROCEDER

Mientras una transacción está en curso, Oracle almacena una imagen de los datos antes de que comience la transacción. Esta imagen es utilizada por otras sesiones que acceden a los datos involucrados en la transacción. También se utiliza para cancelar una transacción automáticamente si algo sale mal o la sesión cancela la transacción.

Sintaxis para cancelar una transacción

RETROCESO;

El estado de los datos antes de que se cancelara la transacción contiene cambios, pero la información necesaria para cancelar estos cambios está disponible. Esta información es utilizada por otras sesiones para cumplir el principio de aislamiento. La transacción ROLLBACK cancelará todos los cambios, restaurando la imagen de datos antes del inicio de la transacción: todas las filas agregadas se eliminarán, todas lineas eliminadas restaurado, todas las filas en las que los valores cambiaron volverán a estado original. Otras sesiones ni siquiera sabrán que pasó algo, nunca vieron el cambio. Y la sesión que inició la transacción después de la cancelación verá los datos tal como estaban antes de que comenzara la transacción.

PUNTO DE GUARDADO

Un punto de guardado permite a los programadores establecer un indicador en una transacción que luego puede usarse para controlar el efecto de cancelar la transacción. En lugar de cancelar toda la transacción y finalizarla, es posible deshacer los cambios realizados después de un indicador específico pero dejar los cambios realizados antes de ese indicador. La acción de la transacción en este momento continúa: la transacción no está confirmada, aún es posible cancelar toda la transacción y los cambios no son visibles para otras sesiones.

Sintaxis de comando

Punto de guardado SAVEPOINT

Este comando crea un punto en la transacción que se puede utilizar más adelante en el comando ROLLBACK. La siguiente tabla muestra el número de filas visibles en la tabla. diferentes sesiones mientras se ejecuta la transacción diferentes momentos tiempo. La tabla utilizada se llama TAB y tiene una columna.

En el ejemplo c, se completaron dos transacciones: la primera se completó con el comando COMMIT y la segunda fue ROLLBACK. Se puede observar que el uso de puntos de guardado afecta solo dentro de la transacción para la sesión que inició la transacción: la segunda sesión no ve nada que no esté confirmado.

SELECCIONARPARAACTUALIZAR

El último comando para gestionar transacciones es SELECCIONAR PARA ACTUALIZAR. Oracle, de forma predeterminada, proporciona nivel más alto concurrencia: la lectura de datos no bloquea la escritura, la escritura no bloquea el cambio. En otras palabras, no hay problema si una sesión intenta leer datos que otra sesión cambia y viceversa. Pero a veces es posible que necesite cambiar este comportamiento y evitar la posibilidad de cambiar los datos que lee la sesión.

El comportamiento típico de una aplicación es recuperar datos usando el comando SELECT, mostrar los datos para que el usuario los vea y permitir que se modifiquen. Dado que Oracle admite trabajo paralelo usuarios, entonces nada impide que otro usuario obtenga los mismos datos. Si ambas sesiones intentan realizar algún cambio, pueden surgir situaciones extrañas. El siguiente ejemplo muestra tal situación.

Esto es lo que verá el primer usuario (suponiendo que se utilice SQL *Plus)

Este resultado es un poco confuso para el usuario. Para resolver este problema, puede bloquear las filas que devolvió la consulta.

seleccione * de las regiones para actualizar;

La directiva FOR UPDATE provocará el bloqueo de las tablas que devuelve la consulta. Otras sesiones no podrán cambiar los datos y, por tanto, los cambios posteriores se realizarán correctamente: otras sesiones no podrán cambiar los datos. Es decir, una sesión tendrá una lectura consistente de los datos, pero el precio de esto será que otras sesiones se atascarán si intentan cambiar los datos que están bloqueados (otras sesiones pueden leer estos datos).

Un bloqueo de fila causado por un comando FOR UPDATE durará hasta que la sesión emita un comando COMMIT o ROLLBACK. El comando de finalización de transacción debe ejecutarse incluso si no ejecutó ningún comando DML.

El llamado “compromiso automático”

Para completar el repaso de cómo se maneja la gestión de transacciones, es necesario despejar todas las dudas sobre el llamado “auto-commit” o compromiso implícito. A menudo escuchará que Oracle confirmará automáticamente. El primer caso es el caso anterior cuando ejecutó el comando DDL, la otra situación es cuando el usuario salió del programa como SQL *Plus.

En realidad es muy simple. No existe tal cosa como una confirmación automática. Cuando ejecuta un comando DDL, funciona el COMMIT normal integrado en el comando DDL. ¿Pero qué pasa cuando sales del programa? Si está utilizando SQL Plus en Windows y emite un comando DML y luego un comando EXIT (EXIT es un comando *Plus SQL, no un comando SQL), su transacción se confirmará. es porque desarrolladores SQL*Además incorporó la llamada al comando COMMIT en el comando EXIT. Si hace clic en la cruz roja en la esquina superior derecha, se llamará el comando ROLLBACK. Esto sucede porque, nuevamente, los desarrolladores de SQL *Plus programaron el programa para que se comportara de esta manera. en otro Sistema operativo El comportamiento del programa SQL Plus puede ser diferente, la única forma de saberlo es probar el programa (o leer código fuente lo cual en el caso del programa SQL Plus es imposible si no trabajas en Oracle usando este programa).

SQL *Plus tiene el comando SET AUTOCOMMIT ON. Llamar a este comando le dice a SQL *Plus cómo manejar las solicitudes de los usuarios: SQL *Plus agregará una llamada al comando COMMIT después de cualquier comando DML. De esta manera todas las solicitudes serán confirmadas tan pronto como se completen. Pero nuevamente, todo esto sucede completamente en el lado del proceso del usuario; la base de datos no tiene ninguna confirmación automática y todos los cambios de larga duración se aislarán de otras sesiones hasta que la solicitud se complete correctamente. Incluso en este caso, si ejecuta una solicitud de ejecución larga y luego, por ejemplo, finaliza el proceso del usuario a través del administrador de tareas, PMON detectará la sesión "fantasma" y cancelará la transacción.




Arriba