Lectura 11 - Transacciones

miércoles, 21 de enero de 2009

INTRODUCCIÓN

En el presente resumen hablaremos de un tema de suma importancia como lo es la Gestión de Transacciones, la cual es una unidad de ejecución de un programa que accede y actualiza varios elementos de datos. También se explica la importancia que tiene el hecho de que las transacciones cuenten con las propiedades ACID.
Incluso hablaremos de los estados de las transacciones donde se presenta un diagrama, en fin, estos y mas temas son tratados en el presente documento.

GESTIÓN DE TRANSACCIONES.

Una transacción es una unidad de la ejecución de un programa que accede y posiblemente actualiza varios elementos de datos. Esta se inicia por la ejecución de un programa de usuario escrito en un lenguaje de manipulación de datos de alto nivel o en un lenguaje de programación (por ejemplo SQL, COBOL, C, C++ o Java) y está delimitado por instrucciones de la forma inicio de transacción y fin transacción. La transacción consiste en todas las operaciones que se ejecutan entre inicio transacción y el fin transacción.
Para asegurar la integridad de los datos se necesita que el sistema de base de datos mantenga las siguientes propiedades de las transacciones, llamadas en conjunto ACID:

Atomicidad. O todas las operaciones de la transacción se realizan adecuadamente en la base de datos o ninguna de ellas.
Consistencia. La ejecución aislada de la transacción (es decir, sin otra transacción que se ejecute concurrentemente) conserva la consistencia de la base de datos.
Aislamiento. Aunque se ejecuten varias transacciones concurrentemente, cada transacción ignora al resto de las transacciones que se ejecuten en el sistema.
Durabilidad. Tras la finalización con éxito de una transacción, los cambios realizados en la base de datos permanecen, incluso si hay fallos en el sistema.
El acceso a la base de datos se lleva a cabo mediante las dos operaciones siguientes:
Leer (x), que transfiere el dato X de la base de datos a una memoria intermedia local perteneciente a la transacción que ejecuta la operación leer.
Escribir (x), que transfiere el dato X desde la memoria intermedia local de la transacción que ejecuta la operación escribir a la base de datos.
En un sistema de base de datos real, la operación escribir no tiene por que producir necesariamente una actualización de los datos en disco; la operación escribir puede almacenarse temporalmente en memoria y llevarse a disco más tarde.

ESTADOS DE UNA TRANSACCIÓN.

En ausencia de fallos, todas las transacciones se completan con éxito. Sin embargo, una transacción puede que no siempre termine su ejecución. Una transacción de este tipo se denomina abortada. Si se pretende asegurar la propiedad de atomicidad, una transacción abortada no debe tener efecto sobre el estado de la base de datos. Así, cualquier cambio que haya hecho la transacción abortada sobre la base de datos debe deshacerse. Una vez que se han deshecho los cambios efectuados por la transacción abortada, se dice que la transacción ha retrocedido.
Parte de la responsabilidad del esquema de recuperaciones es gestionar las transacciones abortadas.
Una transacción que termina con éxito se dice que está comprometida. Una transacción comprometida que haya hecho modificaciones transforma la base de datos llevándola a un nuevo estado consistente, que permanece incluso si hay un fallo en el sistema.
Cuando una transacción se ha comprometido no se pueden deshacer sus efectos abortándola. La única forma de deshacer los cambios de una transacción comprometida es ejecutando una transacción compensadora.
Es necesario precisar qué se entiende por terminación con éxito de una transacción. Se establece por tanto un modelo simple abstracto de transacción. Una transacción debe estar en uno de los estados siguientes:
*Activa, el estado inicial; la transacción permanece en este estado durante su ejecución.
*Parcialmente comprometida, después de ejecutarse la última instrucción.
*Fallida, tras descubrir que no puede continuar la ejecución normal.
*Abortada, después de haber retrocedido la transacción y restablecido la base de datos a su estado anterior al comienzo de la transacción.
*Comprometida, tras completarse con éxito.

Una transacción comienza en el estado activa, cuando acaba su última instrucción pasa al estado de parcialmente comprometida. En este punto la transacción ha terminado su ejecución, pero es posible que aún tenga que ser abortada, puesto que los datos actuales pueden estar todavía en la memoria principal y puede producirse un fallo en el hardware antes de que se complete con éxito.
El sistema de base de datos escribe en disco la información suficiente para que, incluso al producirse un fallo, puedan reproducirse los cambios hechos por la transacción al reiniciar el sistema tras el fallo. Cuando se termina de escribir esta información la transacción pasa al estado comprometida.
Una transacción llega al estado fallida después de que el sistema determine que dicha transacción no puede continuar su ejecución normal. Una transacción de este tipo se debe retroceder. Después pasa al estado abortado. En este punto, el sistema tiene dos opciones:
*Reiniciar la transacción, pero sólo si la transacción se ha abortado a causa de algún error hardware o software que no lo haya provocado la lógica interna de la transacción. Una transacción reiniciada se considera una nueva transacción.
*Cancelar la transacción, Normalmente se hace esto si hay algún error interno lógico que sólo se puede corregir escribiendo de nuevo el programa de aplicación, o debido a una entrada incorrecta o debido a que no se han encontrado los datos deseados en la base de datos.
Cuando una escritura externa observable tiene lugar, no puede borrarse puesto que puede haber sido vista fuera del sistema de base de datos. Muchos sistemas permiten que tales escrituras tengan lugar sólo después de que la transacción llegue al estado comprometida. Una manera de implementar dicho esquema es hacer que el sistema de base de datos almacene temporalmente cualquier valor asociado con estas escrituras externas en memoria no volátil, y realice las escrituras actuales sólo si la transacción llega al estado comprometida. Si el sistema falla después de que la transacción llegue al estado comprometida, pero antes de que finalicen las escrituras externas, el sistema de base de datos puede llevar a cabo dichas escrituras externas (usando los datos de la memoria no volátil) cuando el sistema se reinicie.

IMPLEMENTACIÓN DE LA ATOMICIDAD Y LA DURABILIDAD

El componente de gestión de recuperaciones de un sistema de base de datos implementa el soporte para la atomicidad y la durabilidad. En primer lugar consideramos un esquema simple pero extremadamente ineficiente denominado copia en la sombra. Este esquema asume que la base de datos es simplemente un archivo en disco. En disco se mantiene un puntero llamado puntero_bd que apunta a la copia actual de la base de datos. Una transacción que quiera actualizar una base de datos crea primero una copia completa de dicha base de datos. Todos los cambios de hacen en la nueva copia de la base de datos dejando la copia original, la copia en la sombra, inalterada. Si en cualquier punto hay que abortar la transacción, la copia nueva simplemente se borra. La copia antigua de la base de datos no se ve afectada.
Si la transacción se completa, se compromete como sigue. En primer lugar se consulta al sistema operativo para asegurarse de que todas las páginas de la nueva copia de la base de datos se han escrito en disco, después de terminar esta orden se actualiza el puntero para que apunte a la nueva copia de la base de datos.
Si la transacción falla en algún momento antes de actualizar puntero_bd, el contenido de la base de datos anterior no se ve afectado. Se puede abortar la transacción simplemente borrando la nueva copia de la base de datos. Una vez que se ha comprometido la transacción, puntero_bd apunta a todas las modificaciones que ésta ha realizado en la base de datos. De este modo, o todas las modificaciones de la transacción se ven reflejadas o ninguna de ellas, independientemente del fallo de la transacción.
La implementación depende realmente de que escribir puntero_bd sea una operación atómica; es decir, o se escriben todos sus bytes o ninguno de ellos. Si se escribieran algunos de los bytes del puntero y otros no, el puntero no tendría sentido y al reiniciarse el sistema no se podrían encontrar ni la versión anterior ni la nueva de la base de datos. Afortunadamente los sistemas de disco proporcionan actualizaciones atómicas de bloques enteros, o al menos de un sector del disco.
De este modo, la implementación de la copia en la sombra del componente de gestión de recuperaciones asegura las propiedades de atomicidad y durabilidad de las transacciones.

EJECUCIONES CONCURRENTES

Los sistemas de procesamiento de transacciones permiten normalmente la ejecución de varias transacciones concurrentemente. Permitir esto provoca complicaciones en la consistencia de los mismos. Asegurar la consistencia a pesar de la ejecución concurrente de las transacciones requiere un trabajo extra; es mucho más sencillo exigir que las transacciones se ejecuten secuencialmente, es decir, una a una, comenzando cada una sólo después de que la anterior se haya completado. Sin embargo, existen dos buenas razones para permitir la concurrencia.
Productividad y utilización de recursos mejoradas. Una transacción consiste en varios pasos, Algunos implican operaciones de E/S; otros implican operaciones de UCP, La UCP y los discos pueden trabajar en paralelo en una computadora. Por tanto, las operaciones de E/S se pueden realizar en paralelo con el procesamiento de la UCP. Se pueden ejecutar varias transacciones en paralelo.
Todo esto incrementa la productividad del sistema, es decir, en el número de transacciones que puede ejecutar en un tiempo dado. Análogamente, la utilización del procesador y del disco aumenta también; en otras palabras, el procesador y el disco está menos tiempo desocupado o sin hacer ningún trabajo útil.
Tiempo de espera reducido. Debe haber una mezcla de transacciones que se ejecutan en el sistema, algunas cortas y otras largas. Si las transacciones se ejecutan secuencialmente, la transacción corta debe esperar a que la transacción larga anterior se complete, lo cual puede llevar a un retardo impredecible en la ejecución de la transacción. Si las transacciones operan en partes diferentes de la base de datos es mejor hacer que se ejecuten concurrentemente, compartiendo los ciclos de la UCP y los accesos a disco entre ambas. La ejecución concurrente reduce los retardos impredecibles en la ejecución de las transacciones. Además se reduce también el tiempo medio de respuesta: El tiempo medio desde que una transacción comienza hasta que se completa.
La razón para usar la ejecución concurrente en una base de datos es esencialmente la misma que para usar multiprogramación en un sistema operativo.
El sistema de base de datos debe controlar la interacción entre las transacciones concurrentes para evitar que se destruya la consistencia de la base de datos. Esto se lleva a cabo a través de una serie de mecanismos denominados esquemas de control de concurrencia.

SECUENCIALIDAD

El sistema de base de datos debe controlar la ejecución concurrente de las transacciones para asegurar que el estado de las transacciones para asegurar que el estado de la base sigue siendo consistente. Antes de examinar cómo debe realizar esta tarea, el sistema de base de datos hay que entender primero las planificaciones que aseguran la consistencia y las que no.
Puesto que ls transacciones son programas, es difícil calcular cuáles son las operaciones exactas que realiza una transacción y cómo interaccionan las operaciones de varias transacciones. Por este motivo no se van a interpretar los tipos de operaciones que puede realizar una transacción sobre un elemento de datos. En lugar de esto se consideran sólo dos operaciones: leer y escribir. Se asume así que entre una instrucción leer y otra escribir sobre un elemento de datos, una transacción puede realizar una secuencia arbitraria de operaciones con la copia que reside en la memoria intermedia local de dicha transacción. Existen dos tipos de secuencialidad, en cuanto a conflictos y en cuanto a vistas.

RECUPERABILIDAD

Si la transacción Ti falla, por la razón que sea, es necesario deshacer el efecto de dicha transacción para asegurar la propiedad de atomicidad de la misma. En un sistema que permita la concurrencia es necesario asegurar también que toda transacción Ti que dependa de Ti se aborta también. Para alcanzar esta garantía, es necesario poner restricciones al tipo de planificaciones permitidas en el sistema.
Existen diferentes tipos de planificaciones, como lo son las recuperables, que son las que para todo par de transacciones lee elementos de datos que ha escrito previamente Ti, la operación comprometer Ti aparece antes que la de T; planificaciones sin cascada, incluso si una planificación es recuperable, hay que retroceder varias transacciones para recuperar correctamente el estado previo a un fallo en una transacción T1. (Es un fenómeno en el cual un fallo en una única transacción provoca una serie de retrocesos de la transacción provoca una serie de retrocesos de la transacción.

IMPLEMENTACIÓN DEL AISLAMIENTO

Existen varios esquemas de control de concurrencia que se pueden utilizar para asegurar que, incluso si se ejecutan concurrentemente muchas transacciones, sólo se generen planificaciones aceptables sin tener en cuenta la forma en que el sistema operativo comparte en el tiempo los recursos (tales como el tiempo de UCP) entre las transacciones.
El objetivo de los esquemas de control de concurrencia es proporcionar un elevado grado de concurrencia, al mismo tiempo que asegurar que todas las planificaciones que se generan son secuenciales en cuanto a conflictos o en un cuanto a vistas y son sin cascada.

DEFINICIÓN DE TRANSACCIONES EN SQL

Un lenguaje de manipulación de datos debe incluir una constructora para especificar el conjunto de acciones que constituyen una transacción.
En la norma SQL se especifica el comienzo de una transacción explícitamente. Las transacciones se terminan con una de las instrucciones SQL siguientes:
Commit work compromete la transacción actual y comienza una nueva.
Rollback work provoca que la transacción actual aborte.
La palabra clave work es opcional en ambas instrucciones. Si el programa termina sin ninguna de estas órdenes, los cambios o bien se comprometen o bien se retroceden; en la norma no se especifica cuál de las dos acciones tiene lugar, y depende de la implementación.
La norma específica también que el sistema debe garantizar tanto la secuencialidad como la ausencia de retroceso en cascada. La definición de secuencialidad que usa la norma es que la planificación debe tener el mismo efecto que tendría una planificación secuencial. De este modo son aceptables tanto la secuencialidad en cuanto a conflictos como la secuencialidad en cuanto a vistas. La norma SQL-92 permite también que una transacción especifique que puede ejecutarse de forma que se convierta en no secuenciable con respecto a otras transacciones.

COMPROBACIÓN DE LA SECUENCIALIDAD

Cuando se diseñan esquemas de control de concurrencia hay que demostrar que las planificaciones que genera el esquema son secuenciales. Para hacer esto se debe entender primero la forma de determinar si, dada una planificación concreta P es secuencial.
El orden de secuencialidad se puede obtener a través de la ordenación topológica, la cual determina un orden lineal, que consiste en el orden parcial del grafo de precedencia. En general se pueden obtener muchos órdenes lineales posibles a través de la ordenación topológica.
Para poder probar la secuencialidad en cuanto a conflictos hay que construir el grafo de precedencia e invocar a un algoritmo de detección de ciclos. Los algoritmos de detección de ciclos, tales como los que se basan en la búsqueda primero en profundidad, requieren del orden de n operaciones, De este modo se tiene un esquema práctico para determinar la secuencialidad en cuanto a conflictos.
La comprobación de la secuencialidad en cuanto a vistas es más complicada. De hecho, se ha demostrado que el problema de determinar la secuencialidad en cuanto a vistas es NP-completo. Por tanto, seguramente no exista ningún algoritmo eficiente para comprobar la secuencialidad en cuanto a vistas.

CONCLUSIÓN

Por último podemos decir que realmente es importante conocer la forma en que podemos asegurar la integridad de los datos, también conocer los diferentes estados en que puede encontrarse una transacción, y la transición que estas llevan para pasar de un estado a otro, como el componente de gestión implementa el soporte para la atomicidad y la durabilidad y la comprobación de secuencialidad, etc.

BIBLIOGRAFÍA

Fuente: Silverschatz Capitulo 15.

0 Comments: