Formato para prácticas de laboratorio CARRERA PLAN DE ESTUDIO CLAVE ASIGNATURA NOMBRE DE LA ASIGNATURA LSC 2009-2 12001 Administración de Bases de Datos PRÁCTICA No. 6 LABORATORIO DE NOMBRE DE LA PRÁCTICA Bases de Datos Distribuidas DURACIÓN (HORA) Transacciones y Control de Concurrencia. 2 1. INTRODUCCIÓN Instrucciones de transacción (Transact-SQL) Una transacción es una unidad única de trabajo. Si una transacción tiene éxito, todas las modificaciones de los datos realizadas durante la transacción se confirman y se convierten en una parte permanente de la base de datos. Si una transacción encuentra errores y debe cancelarse o revertirse, se borran todas las modificaciones de los datos. SQL Server funciona en los siguientes tres modos de transacción. Transacciones de confirmación automática Cada instrucción individual es una transacción. Transacciones explícitas Cada transacción se inicia explícitamente con la instrucción SACTION y se termina explícitamente con una instrucción COMMIT o ROLLBACK. Transacciones implícitas Se inicia implícitamente una nueva transacción cuando se ha completado la anterior, pero cada transacción se completa explícitamente con una instrucción COMMIT o ROLLBACK. Transacciones de ámbito de lote Una transacción implícita o explícita de Transact-SQL que se inicia en una sesión de MARS (conjuntos de resultados activos múltiples), que solo es aplicable a MARS, se convierte en una transacción de ámbito de lote. Si no se confirma o revierte una transacción de ámbito de lote cuando se completa el lote, SQL Server la revierte automáticamente. Concurrencia. El sistema de base de datos normalmente está siendo accedido simultáneamente por muchos usuarios tanto para hacer consultas como actualizaciones. Formuló Lissethe G. Lamadrid López y estudiantes de lsc ciclo 2013-1 Revisó Josefina Mariscal Camacho Aprobó Autorizó David I. Rosas Almeida Nombre y Firma del Maestro Nombre y Firma del Responsable de Programa Educativo Nombre y Firma del Responsable de gestión de Calidad Nombre y Firma del Director / Representante de la Dirección Página 1 de 13 Revisión 1.
Serialización. Sea cual sea el orden de ejecución de las operaciones, el estado de la BD debe quedar como si hubiese ejecutado un procedimiento primero luego otro. A esto se le llama una ejecución serializable. Nota: No se necesita que los procedimientos siempre se ejecuten uno tras otro, solo se necesita que el resultado sea serializable. Atomicidad. La ejecución de una operación es atómica si el estado de la BD luego de una operación, es como si todos sus componentes (tareas ) se hubiesen ejecutado o como si ninguno de ellos lo hubiese hecho. Niveles de aislamiento del motor de base de datos. Las transacciones especifican un nivel de aislamiento que define el grado en que se debe aislar una transacción de las modificaciones de recursos o datos realizadas por otras transacciones. Los niveles de aislamiento se describen en cuanto a los efectos secundarios de la simultaneidad que se permiten, como las lecturas desfasadas o ficticias. Control de los niveles de aislamiento de transacción: Controla si se realizan bloqueos cuando se leen los datos y qué tipos de bloqueos se solicitan. Duración de los bloqueos de lectura. Si una operación de lectura que hace referencia a filas modificadas por otra transacción: Se bloquea hasta que se libera el bloqueo exclusivo de la fila. Recupera la versión confirmada de la fila que existía en el momento en el que empezó la instrucción o la transacción. Lee la modificación de los datos no confirmados. Problemas que se presentan en niveles de aislamiento. Lecturas sucias: lee datos que no han llegado a validarse. Lecturas no repetibles: Dos sentencias select iguales y consecutivas podrían devolver datos diferentes. Datos fantasma: en dos sentencias select iguales y consecutivas podrían aparecer y desaparecer filas. 2. OBJETIVO (COMPETENCIA) Al finalizar el alumnos tendrá los conocimientos para establecer los diferentes niveles de aislamiento y asi controlar el comportamiento de los bloqueos (locks) mediante instrucciones Transact-SQL emitido por una conexión a SQL Server. Asi como configurar la opción de configuración del servidor de Locks en SQL Server 2012 mediante SQL Server Management Studio y/o Transact-SQL, y esto conllevara a que utilize transacciones explicitas con las sentencias Begin Transaction / Commit o Rollback Transaction. Página 2 de 13 Revisión 1.
3. FUNDAMENTO Los problemas de serializacion y atomicidad pueden ser resueltos usando transacciones. Una transacción esta compuesta por un grupo de instrucciones de SQL que se ejecutan atomicamente (o se ejeccutan todas o ninguna debería hacerlo). Por default una transacción exige ejecuciones serializables. Una transaccion se comienza con una instrucción begin transaction. La instrucción commit termina la transacción en forma exitosa y hace permanente cualquier cambio realizado a la BD durante la transacción. La instrucción rollback aborta la transacción y la hace terminar en forma no exitosa, cualquier cambio que la transacción pudo hacer a la BD se deshace. Se puede hacer rollback para cualquier conjunto de instrucciones, no necesariamente dentro de una transacción. Motivos de transacciones abortadas. Alguna excepción detectada que hace que el programa no pueda continuar. alguna falla del programa, Software de la BD inclusive falla del hardware o energía eléctrica. Si en control de concurrencia se detecta un conflicto. Si en control de concurrencia se detecta un deadloack. Problemas que se presentan en niveles de aislamiento. Lecturas sucias: lee datos que no han llegado a validarse. Lecturas no repetibles: Dos sentencias select iguales y consecutivas podrían devolver datos diferentes. Datos fantasma: en dos sentencias select iguales y consecutivas podrían aparecer y desaparecer filas. Control de concurrencia. Foma en que el DBMS maneja las ejecuciones paralelas en la BD. Tiene dos enfoques. Pesismita y optimista. Optimista. Este enfoque supone que los conflictos o problemas que puedan ocurrir son escasos. Permitir acceso concurrente y deshacer las acciones problemáticas. Pesimista. Aquí asume que es muy probable y casi seguro que ocurran problemas. actua a la defensiva impidiendo la aparición de conflictos usando locks. Un lock es una estructura que solo puede ser adquirida por un hilo de ejecución (thread.manera de bifurcarse de dos o mas tareas) a la vez. Si dos ejecuciones tratan de obtener un lock para actualizar una tabla, la primera que trate de obtenerlo tendrá acceso exclusivo a la tabla, la segunda debe esperar a que la primera lo suelte para obtener el acceso. los locks pueden tener distintas granuralidades ( la forma en que se define los datos) bases de datos, tabla, tupla, atributo. Página 3 de 13 Revisión 1.
además de locks exclusivos existen locks de solo lectura o locks compartidos que pueden estar simultáneamente siendo utilizados por distintas ejecuciones. Si no se hace un adecuado control de concurrencia, se pueden presentar dos anomalías, en primer lugar se pueden perder actualizaciones provocando que los efectos de algunas transacciones no se reflejen en la base de datos. En segundo término pueden presentarse recuperaciones de información inconsistentes. Administracion de transacciones por niveles de aislamiento (Transact-SQL). Read uncommited o lecturas no confirmadas. En este nivel los usuarios pueden leer datos que aun no están confirmados, y que por lo tanto pueden llegar a no existir nunca. Los problemas o desventajas que presenta este nivel son: Lecturas sucias, lecturas no repetibles y datos fantasma. Se debe ser cuidadoso si se usa este nivel de aislamiento ya que podría hacer que los usuarios se basen en datos que realmente no han existido nunca y que por tanto son erróneos. En muchas ocasiones se usa para evitar bloqueos, si asi se realiza se debe de asegurar que las consecuencias son admisibles. Read commited o lecturas confirmadas. Este es el nivel de aislamiento por defecto en SQL server, no lee datos que no estén confirmados, si no que se esperaría (se quedaría bloqueado) a que los datos estén confirmados. los bloqueos que establece mientras se lee la información, tan solo permanecen activos durante el tiempo de la ejecución, no durante toda la transacción y no se ve bloqueado por lecturas. Los problemas o desventajas que tiene este nivel son: lecturas no repetibles y Datos fantasma. En este nivel las lecturas solo se ven bloquedas por las escrituras, y las escrituras rara vez se ven bloquedas por lecturas, y además solo durante un muy corto periodo de tiempo, de tal forma que no suelen producirse muchos interbloqueos. Repeatable read o lecturas repetibles. En este nivel garantiza que dos select consecutivas dentro de una transacción devolverán la misma información y lo hace creando bloqueos compartidos sobre los registros que lee de tal forma que no pueden ser modificados. El problema que presenta o desventaja son los Datos fantasma. En este nivel las lecturas solo se ven bloqueadas por las escrituras, pero las escrituras se ven bloqueadas por lecturas durante el tiempo que dura la transacción que lee de tal forma que es más frecuente encontrar problemas de bloqueos. Serializable. Este nivel de aislamiento no tiene el problema de datos fantasma, por que cuando realiza un select, crea bloqueos compartidos (shared locks) no solo sobre los registros que existen, sino sobre los nuevos que pudiesen llegar (los inserts), de tal forma que dos instrucciones select consecutivas dentro de la misma transacción devolverán exactamente los mismos datos. En muchas ocasiones los administradores eligen este nivel porque es lo más parecido a estar solo en el sistema, pero en este nivel se necesita crear un número considerable de bloqueos para poder garantizar estas lecturas repetibles evitando datos fantasma. Aquí las lecturas solo se ven bloqueadas por las escrituras, pero las escrituras se ven bloqueadas por lecturas incluso escrituras de tipo insert que en el nivel de aislamiento REPEATABLE READ no se verían afectadas. Este es el nivel máximo de aislamiento y también genera el nivel máximo de bloqueos, analice si realmente necesita estas características antes de usarlo. Página 4 de 13 Revisión 1.
Snapshot o agente de instantánea. Cumple los mismos requisitos que el serializable, es decir no tiene ninguno de los problemas de lecturas sucias, ni lecturas no repetibles, ni lecturas fantasma, pero no se basa en una estrategia de bloqueo para conseguirlo, si no es una estrategia de versiones de las filas. Esta estrategia permite evitar todos los problemas descritos sin necesidad de bloquear las filas, de tal forma que una sentencia select devolverá exactamente los mismos datos cada vez que se ejecute. El nivel de aislamiento de instantáneas puede mostrar conflictos en actualizaciones, el motivo es sencillo, si las sentencias select devuelven siempre la misma información pero no han impedido que otros usuarios cambien la información, en el momento en que la transacción actual vaya a cambiar algún dato, debe comprobar que los datos que están validados en la base de datos son los mismos que existían cuando fueron leídos y versionados la primera vez, en caso contrario podríamos sobrescribir modificaciones de otros usuarios pero basados en datos que ya no existen. Conjunto de transacciones por nivel de aislamiento (Transact-SQL). Controla el comportamiento de bloqueos y versiones de fila de instrucciones Transact-SQL emitido por una conexión a SQL Server. Sintaxis SET TRANSACTION ISOLATION LEVEL { READ UNCOMMITTED READ COMMITTED REPEATABLE READ SNAPSHOT SERIALIZABLE } [ ; ] 4. PROCEDIMIENTO (DESCRIPCIÓN) A) EQUIPO NECESARIO MATERIAL DE APOYO Equipo de cómputo SQL Server 2012 B) DESARROLLO DE LA PRÁCTICA Haga los siguientes ejemplos, donde se establece el nivel de aislamiento de la transaccion. Para cada instrucción de Transact-SQL que sigue, SQL Server mantiene todos los bloqueos compartidos hasta el final de la transacción. Nota : Para cada ejemplo se uso una base de datos con nombre PRUEBA y una tabla EMPLEADO, se recomienda que utilice alguna que haya creado anteriormente. QUERY 1 USE PRUEBA; Página 5 de 13 Revisión 1.
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; SACTION; SELECT * FROM EMPLEADO; COMMIT TRANSACTION; QUERY 2 USE PRUEBA; SET TRANSACTION ISOLATION LEVEL READ COMMITTED; SACTION; SELECT * FROM EMPLEADO; COMMIT TRANSACTION; QUERY 3 USE PRUEBA; SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; SACTION; SELECT * FROM EMPLEADO; COMMIT TRANSACTION; QUERY 4 USE PRUEBA; SET TRANSACTION ISOLATION LEVEL SNAPSHOT; SACTION; SELECT * FROM EMPLEADO; COMMIT TRANSACTION; QUERY 5 USE PRUEBA; Página 6 de 13 Revisión 1.
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; SACTION; SELECT * FROM EMPLEADO; COMMIT TRANSACTION; Configuración de la opción del servidor de Locks. Aquí se describe cómo configurar la opción de configuración del servidor de Locks en SQL Server 2012 mediante SQL Server Management Studio o Transact-SQL. La opción de locks establece el número máximo de locks disponibles, lo que limita la cantidad de memoria que utiliza el motor de base de datos de SQL Server para ellos. El valor predeterminado es 0, lo que permite que el motor de base de datos para asignar y desasignar estructuras lock dinámicos, basado en el cambio de los requisitos del sistema. Cuando el servidor se inicia con locks establecidos en 0, el administrador de locks adquiere suficiente memoria del motor de base de datos para un grupo inicial de 2.500 estructuras de bloqueo(locks). A medida que se agota el grupo de bloqueo, más memoria se adquiere para el grupo. En general, si se requiere más memoria para el grupo de bloqueo que está disponible en el grupo de memoria del motor de base de datos y más memoria de la computadora está disponible (el umbral de memoria máxima del servidor no se ha alcanzado), El motor de base de datos le asigna memoria dinámicamente para satisfacer la demanda de bloqueos. Sin embargo, si asignar esa memoria causaria paginación a nivel del sistema operativo (por ejemplo, si se está ejecutando otra aplicación en la misma computadora como una instancia de SQL Server y usando esa memoria), no se asigna más espacio de bloqueos. El grupo de bloqueo dinámico no adquiere más del 60 por ciento de la memoria asignada al motor de base de datos. Después de que el grupo de bloqueo ha alcanzado el 60 por ciento de la memoria adquirida por una instancia del motor de base de datos, o no haya más memoria disponible en el equipo, nuevas solicitudes de bloqueos generan un error. Permitir que SQL Server utilice bloqueos dinámicamente es la configuración recomendada. Sin embargo, puede establecer bloqueos y anular la capacidad de SQL Server para asignar los recursos de bloqueo de forma dinámica. Cuando locks se establece en un valor distinto de 0, el motor de base de datos no puede asignar más locks que el valor especificado en los locks. Aumente este valor si SQL Server muestra un mensaje que se ha superado el número de bloqueos disponibles. Debido a que cada bloqueo consume memoria (96 bytes por bloqueo), el aumento de este valor puede requerir el aumento de la cantidad de memoria dedicada para el servidor. La opción de bloqueos afecta también cuando se produce la extensión de bloqueo. Página 7 de 13 Revisión 1.
Cuando los locks se establece en 0, la extensión de bloqueo se produce cuando la memoria usada por las estructuras de bloqueo actual llega al 40 por ciento del grupo de memoria del motor de base de datos. Cuando los locks NO se establece en 0, la extensión de bloqueo se produce cuando el número de bloqueos alcanza el 40 por ciento del valor especificado para locks. Para configurar las opciones LOCKS usando Management Studio. 1. En el explirador de objetos, de click derecho y seleccione Properties. 2. Click en el nodo Advanced. 3. Bajo Parallelism, teclee el valor deseado para la opción locks. Use la opción locks para establecer el numero máximo de locks disponibles, sin limitar la cantidad de memoria que sql server utiliza para ellos. Usando TRANSACT-SQL. Copie y pegue el siguiente ejemplo en la ventana de consulta y haga clic en Ejecutar. Este ejemplo muestra cómo utilizar sp_configure para establecer el valor de la opción locks para establecer el número de bloqueos disponibles para todos los usuarios a 20.000. Transact-SQL Use PRUEBA ; sp_configure 'show advanced options', 1; RECONFIGURE; sp_configure 'locks', 20000; RECONFIGURE; Configuración de la opción 'Mostrar opciones avanzadas' cambio de 0 a 1. Ejecute la instrucción RECONFIGURE para instalar. Opción de configuración de Bloqueos' cambio desde 0 hasta 20000. Ejecute la instrucción RECONFIGURE para instalar. Antes de continuar. Cree una base de datos llamada EMPRESA con las tablas EMPLEADOS (ID int, NOMBRE varchar) CLIENTES (ID int, PAIS varchar) AUDITORIA (ID int, EMPLEADOS int), e ingrese algunos datos. Realice las transacciones sql que se presentan. DELETE FROM CLIENTES WHERE PAIS = 'MEXICO' Aquí se ejecutara el delete para todos los clientes que cumplan la condición de MEXICO, si hay un error al intentar borrar un cliente se hará un rollback y no se borrara ninguno, esto se debe a que el delete al igual que el insert y update internamente arman una transacción. Página 8 de 13 Revisión 1.
Las transacciones explicitas son aquellas que nosotros indicamos con la sentencia Begin Transaction / Commit o Rollback Transaction. SACTION INSERT INTO EMPLEADOS (ID, NOMBRE) VALUES (1,'LISSETHE') DELETE FROM AUDITORIA WHERE EMPLEADO = 1 COMMIT TRAN Aquí el commit es el que confirmara la transacción y el rollback es el que la deshará, pero aquí hay algunos detalles muy importantes en su comportamiento cuando usamos transacciones anidadas. Ejecute el siguiente ejemplo; CREATE TABLE #T1 (ID INT, NOMBRE VARCHAR(50)) CREATE TABLE #T2 (ID INT, FECHA DATETIME NOT NULL) BEGIN TRY INSERT INTO #T1 VALUES (1,'LISSETHE') INSERT INTO #T1 VALUES (1,GETDATE()) COMMIT TRAN END TRY BEGIN CATCH ROLLBACK TRAN SELECT @@ERROR END CATCH En el ejemplo hiciste dos insert y si hay algún error entras en la sección del Catch y lo primero que haces es el rollback para luego mostrar el error. Este es un ejemplo donde si no hay problemas se harán los dos insert y el commit los confirmara y de haber un error en algún insert se hará Rollback. Anidar transacciones Página 9 de 13 Revisión 1.
Que sucede si necesitamos manejar transacciones anidadas?. Ejecutamos un Store que abre una transacción que llama a otro Store que abre otra transacción y así, o bien en el mismo código. Aquí primero debes comprender como impacta un Rollback y un Commit y es donde mayor confusión quizás hay. El Rollback hará que se deshagan todas las transacciones o sea si armas una transacción dentro de otra y la segunda hace un rollback hará que también la primera lo haga, en cambio el commit lo hará por cada bloque a menos que apliquemos un commit en el bloque externo lo cual hará que todo se comitee. Para poder evaluar cuantas transacciones tienes abiertas utiliza la variable @@Trancount Código del primer ejemplo muestra cómo funciona el Rollback USE TEMPDB go CREATE TABLE Cabecera (id int, fecha Datetime) go CREATE TABLE Detalle (CabeceraId int, linea int NOT NULL, Cantidad decimal (8,2) NOT NULL) CREATE TABLE Auditoria (Id int identity, Fecha datetime not null ) -- Ejecute el Script por pasos para ir comprendiendo -- ======================================= -- Funcionamiento del Rollback -- ======================================= -- Vemos que no hay Transacciones -- Abrimos una transacción -- hacemos los insert INSERT INTO Cabecera VALUES (1,GETDATE()) Página 10 de 13 Revisión 1.
INSERT INTO Detalle Values (1,1,100) -- vemos las transacciones abiertas (1) -- Abrimos otra transacción -- Verificamos que Trancount se incremento en 1 -- Hacemos un Rollback ROLLBACK TRAN go -- Verificamos que Trancount quedo en 0 -- Lo cual ha hecho un rollback de todo Ejemplo cómo funciona el Commit con el manejo de transacciones -- ======================================= -- Funcionamiento del Commit -- ======================================= -- Vemos que no hay Transacciones -- Abrimos una transacción -- hacemos los insert INSERT INTO Cabecera VALUES (1,GETDATE()) INSERT INTO Detalle Values (1,1,100) -- vemos las transacciones abiertas (1) -- Abrimos otra transacción -- Verificamos que Trancount se incremento en 1 Página 11 de 13 Revisión 1.
-- Hacemos un Rollback INSERT INTO Auditoria (Fecha) VALUES (GETDATE()) COMMIT TRAN -- Verificamos que Trancount decrecio en 1 COMMIT TRAN -- Hacemos el utimo Commit -- Verificamos que Trancount queda en 0 go Redacte el comportamiento que tenemos entre el Rollback y el Commit. Control de errores y transacciones Ahora que conoces el manejo del Rollback es muy distinto al del Commit Tran, ahora debes hacerte la siguiente pregunta. Como hacemos para controlar los errores? la buena práctica es que ante un error lo primero que se haga sea un Rollback pero que sucede si hubo un rollback anterior y el TranCount quedo en 0? Lo que debes hacer es en control del error verificar primero la variable Trancount y si es mayor que 0 entonces si hacer el Rollback. Ejemplo: -- ======================================= -- Manejo de Errores & transacciones -- ======================================= -- Abrimos una transacción BEGIN TRY -- hacemos los insert INSERT INTO Cabecera VALUES (1,GETDATE()) INSERT INTO Detalle Página 12 de 13 Revisión 1.
Values (1,1,100) -- Abrimos otra transacción -- Verificamos que Trancount se incremento en 1 END TRY -- Generamos un error para ir al bloque CATCH INSERT INTO Auditoria (Fecha) VALUES (NULL) -- Verificamos que Trancount quedo en 0 -- Lo cual ha hecho un rollback de todo -- Control de errores BEGIN CATCH IF @@TRANCOUNT > 0 BEGIN ROLLBACK TRAN END SELECT ERROR_MESSAGE() END CATCH C) CÁLCULOS Y REPORTE 5. RESULTADOS Y CONCLUSIONES 6. ANEXOS 7. REFERENCIAS http://msdn.microsoft.com/en-us/library/ms173763.aspx http://technet.microsoft.com/en-us/library/ms190253.aspx Página 13 de 13 Revisión 1.