670 likes | 1k Views
Aislamiento Bloqueo. Necesidad de aislamiento. En ambientes multiusuario, las transacciones acceden a los datos simultáneamente Datos que no estén aislados pueden estar errados. Bloqueo (locking).
E N D
Aislamiento Bloqueo
Necesidad de aislamiento • En ambientes multiusuario, las transacciones acceden a los datos simultáneamente • Datos que no estén aislados pueden estar errados
Bloqueo (locking) • Mecanismo automático que aisla los datos para prevenir conflictos de los datos que se están modificando
Alcance de los candados • El alcance de un candado determina cuántos datos se aislan • Tres alcances
Tipos de candados • El tipo de candado determina la extensión del aislamiento de datos de otras transacciones • Tres tipos de candados • Shared • Exclusive • Update
Candados Shared • Usado por sentencias que leen datos (selects) • Otros procesos pueden leer los datos (coloca candado shared), pero ningún proceso puede cambiar los datos (coloca candado exclusive)
Candados exclusive • Usado por sentencias que cambian datos (inserts, updates, deletes) • Ningún otro proceso puede leer los datos (coloca candado shared) o cambiar los datos (coloca candado exclusive sobre la página)
Candados shared y exclusive Nota: Se intenta involucrar dos tablas: un select para publishers y un delete para authors Nota: Se usa la opción holdlock, la cual asegura que los candados shared no se liberan hasta cuando concluya la transacción. • El instructor tipea: begin tran select * from pubs2..publishers holdlock delete from pubs2..authors • Espera ver los datos de publishers: select * from pubs2..publishers
Candados update • Usado por operaciones que pueden o no cambiar los datos (updates, deletes) • Cuando el proceso primero escanea los datos, le aplica un candado update. Otros procesos pueden colocar candados shared, pero ningún proceso puede colocar candados exclusive o update
Resúmen de tipos de candados *Updates y deletes usan candados exclusive solamente para encontrar los datos que necesitan modificar
Esquema de bloqueo • Esquema de bloqueo es un atributo de la tabla que determina qué datos asociados con la tabla están bloqueados
bloqueo “allpages” • Se pueden bloquear las páginas de índices • El servidor usa candados de tabla y candados de página, pero no candados de fila
Bloqueo “datapages” • Las páginas de índices nunca se bloquean • El servidor usa candados de tabla y candados de página, pero no candados de fila
Bloqueo “datarows” • Las páginas de índices nunca se bloquean • El servidor usa candados de tabla, candados de página y candados de fila
Fijar el esquema bloqueo • Sintaxis simplificada: create table table_name ( column_name datatype [ NULL | NOT NULL | IDENTITY ] , ... column_name datatype [ NULL | NOT NULL | IDENTITY ] ) [ lock { allpages | datapages | datarows } ] • Ejemplo: create table publishers (pub_id char(4) NOT NULL,pub_name varchar(40) NULL,city varchar(20) NULL,state char(2) NULL)lock datarows • Si no se especifica un esquema de bloqueo, la tabla usa el esquema default de bloqueo
Cambiar el esquema de bloqueo • Sintaxis simplificada: alter tabletable_name lock { allpages | datapages | datarows } • Ejemplo: alter table publishers lock datapages
Ejemplo • Ver el default del esquema de bloqueo actual: sp_configure "lock scheme" • Crear una tabla con el esquema default de bloqueo: create table def_scheme (a int) • Crear una tabla con un esquema de bloqueo especifico: create table dpl_scheme (a int) lock datapages • Ver el esquema de bloqueo ambas tablas: sp_help def_scheme exec sp_help dpl_scheme
Ejemplo • Cambiar el esquema de bloqueo de la primera tabla: • alter table def_scheme lock datarows • Ver el esquema de bloqueo ambas tablas: • sp_help def_schemeexec sp_help dpl_scheme • Borrar los objetos de base de datos creados: • drop table dpl_schemedrop table def_scheme
Leer datos no aislados • Hay tres tipos de consultas o “reads”, que pueden retornar datos que son inadecuados para limitar el aislamiento de datos • Las características de cómo se hacen estos “reads” son propios de cada DBMS • Hay tres tipo de “reads”: • Dirty reads • Nonrepeatable reads • Phantom reads
Lectura sucia • La transacción 1 modifica datos • La transacción 2 lee los datos modificados antes de que la modificación haya terminado • Esta transacción lee datos “uncommitted” o “dirty”
Lectura no repetible • La transacción 1 lee datos • La transacción 2 modifica esos datos antes de que la primera transacción haya terminado • La primera lectura es ahora “nonrepeatable”
Lectura fantasma • La transacción 1 lee un conjunto de filas que cumplen una condición • La transacción 2 modifica los datos de algunas columnas que no cumplían esa condición y ahora la cumplen, o al contrario • Las filas que aparecen y desaparecen se denominan “phantoms”
Nivel de aislamiento • Un nivel de aislamiento es un conjunto de candados que permiten o no una combinación particular de los tres tipos de lectura: sucia, no repetible o con fantasmas • ANSI define cuatro niveles de aislamiento, cada uno más restrictivo que el anterior
Nivel 1 de aislamiento • Nivel 1 - Comportamiento de select: • Se fijan candados Shared hasta que el select termine la lectura de una fila o página • select espera a que se liberen los candados exclusive
Nivel 2 de aislamiento • Nivel 2 - Comportamiento de select: • Se fijan candados Shared hasta que termine la transacción • Este comportamiento es diferente al del nivel 1 • select espera a que se liberen los candados exclusive • Comportamiento discreto de nivel 2 requiere bloqueo “row-level” • Tables APL y tables DPL no tienen bloqueo “row-level” • Si una consulta con nivel de aislamiento 2 lee una tabla APL o DPL, se forza comportamiento de aislamiento nivel 3
Nivel 3 de aislamiento • Nivel 3 – El nivel más restrictivo: • Nivel 3 - Comportamiento de select: • Se fijan candados shared hasta que termine la transacción • Este comportamiento es diferente al del nivel 1 • select espera a que se liberen los candados exclusive
Nivel 0 de aislamiento • Nivel 0 – El nivel menos restrictivo: • Nivel 0 - Comportamiento de select: • Se fijan candados Shared hastaque select termine la lectura de una fila o página • select ignora los candados exclusive • Este comportamiento es diferente al del nivel 1
Fijar nivel de aislamiento • Sintaxis para aislamiento a nivel de sesión: set transaction isolation level {0 | read uncommitted | 1 | read committed |2 | repeatable read | 3 | serializable } • Sintaxis para aislamiento a nivel de sentencia: select ... at isolation { 0 | read uncommitted |1 | read committed | 2 | read repeatable | 3 | serializable }
holdlock y noholdlock • holdlock forza nivel de ailamiento 3, sin importar el nivel de aislamiento actual • Para select se fijan candados shared hasta que termine la transacción • noholdlock forza nivel de ailamiento 1, sin importar el nivel de aislamiento actual • Para select se liberan los candados shared cuando se ha leido una fila o página • Sintaxis simplificada: selectcolumn_list from table_list [ holdlock | noholdlock ] • Ejemplo: select title from titles holdlock where pub_id = "0877"
Cursor • Un cursor es un mecanismo que sirve para procesar fila por fila los resultados de una consulta
Beneficios de los cursores • Se pueden procesar los datos fila por fila • SQL es un lenguaje orientado a conjuntos • El procesamiento se hace normalmente sobre las filas que cumplan con una condición dada • Los cursors permiten el procesamiento fila por fila • Se pueden modificar los datos fila por fila • Se puede sortear la brecha existente entre la orientación a conjuntos de las bases de datos relacionales y la orientación a filas de muchos lenguajes de programación
Ciclo de vida de un cursor 1. Declarar el cursor 2. Abrir el cursor 3. Tomar cada fila 4. Cerrar el cursor 5. Desasignar el cursor
Paso 1: Declarar el cursor • Cuando se declara un cursor: • Se especifica una consulta • Se especifica un modo para el cursor • De solo lectura • Para actualización
Sintaxis para declarar un cursor • Sintaxis simplificada: declarecursor_name cursor forselect_statement [ for { read only | update [ of column_name_list] } ] • Ejemplo: declare biz_book cursor for select title, title_id from titles where type = "business" for read only go
Paso 2: Abrir el cursor • Cuando se abre el cursor • El servidor crea el conjunto resultado • El apuntador está señalando antes de la primera fila del conjunto respuesta
Sintaxis para la apertura de un cursor • Sintaxis: opencursor_name • Ejemplo: declare biz_book cursor for select title, title_id from titles where type = "business" for read only go declare @title char(80), @title_id char(6) open biz_book fetch biz_book into @title, @title_id while @@sqlstatus = 0 begin -- process @title and @title_id fetch biz_book into @title, @title_id end close biz_book deallocate cursor biz_book
Paso 3: Tomar cada fila • Cuando se ejecuta un fetch: • El cursor señala a la siguiente fila válida • Retorna la siguiente fila válida
Sintaxis de un fetch • Sintaxis: fetchcursor_name [ intofetch_target_list ] • Ejemplo: declare biz_book cursor for select title, title_id from titles where type = "business" for read only go declare @title char(80), @title_id char(6) open biz_book fetch biz_book into @title, @title_id while @@sqlstatus = 0 begin -- process @title and @title_id fetch biz_book into @title, @title_id end close biz_book deallocate cursor biz_book
Pasos 4 y 5: Cerrar y desasignar el Cursor • Cuando se cierra un cursor: • Termina el procesamiento de la consulta hecha • Cuando se desasigna el cursor: • Se liberan todos los recursos de memoria asignados al cursor
Cerrar y desasignar un Cursor • Sintaxis: closecursor_name deallocate cursor cursor_name • Ejemplo: declare biz_book cursor for select title, title_id from titles where type = "business" for read only go declare @title char(80), @title_id char(6) open biz_book fetch biz_book into @title, @title_id while @@sqlstatus = 0 begin -- process @title and @title_id fetch biz_book into @title, @title_id end close biz_book deallocate cursor biz_book
Variables para el manejo de cursores • Se tiene una variable que retorna el número total de filas procesadas (@@rowcount) • Se tiene una variable que indica el estado o resultado de mover el cursor (@@sqlstatus) • Exitoso: se alcanzó una fila válida • Hay un error al tratar de tomar la fila • Ya se procesaron todas las filas
Notas adicionales para fetch • fetch siempre mueve el apuntador a la siguiente fila válida en el conjunto respuesta • Algunos servidores permiten regresarse a una fila anterior • Cerrar y reabrir un cursor hace que el apuntador siempre señale al comienzo • Por default, fetch siempre retorna una fila • Algunos servidores permiten cambiar este defaullt • Sintaxis: set cursorrowsnumberforcursor_name • Ejemplo: set cursor rows 5 for biz_book
Prácticas recomendadas para desarrollo • Siempre especificar el modo del cursor en la sentencia declare • Como los cursores pueden demandar muchos recursos, evitar dejar abiertos los cursores por mucho • Si se ejecuta la misma operación en cada fila del cursor, hay que buscar una alternativa
Ejemplo de cursor declare books_csr cursor for select title_id, type, price from titles for read only go -- List all business and mod_cook books. Show business books -- at 8% increase in price. This cursor allows you to -- selectively manipulate a subset of the rows while -- retaining a single result set. declare @title_id tid, @type char(12), @price money open books_csr -- initial fetch fetch books_csr into @title_id, @type, @price
Ejemplo de cursor while @@sqlstatus = 0 begin if @@sqlstatus = 1 begin raiserror 30001 "select failed" close books_csr deallocate cursor books_csr return end if @type="business" select @title_id, @type,CONVERT(money,@price*1.08) else if @type="mod_cook" select @title_id, @type, @price -- subsequent fetches within loop fetch books_csr into @title_id, @type, @price end