Desarrollo de Bases de Datos - siul02.si.ehu.essiul02.si.ehu.es/~jimena/ABD/fuentes/SQLJ.pdf ·...
-
Upload
truongkhanh -
Category
Documents
-
view
218 -
download
0
Transcript of Desarrollo de Bases de Datos - siul02.si.ehu.essiul02.si.ehu.es/~jimena/ABD/fuentes/SQLJ.pdf ·...
Desarrollo de Bases de Datos
Oscar Díaz - Facultad de Informática - Universidad del País Vasco / Euskal HerrikoUnibertsitatea
SQLJ
Motivación
Utilización de variables compartidas
Compatibilidad de tipos
Recuperación de datos
Tratamiento de excepciones
Contexto de ejecución
Contexto de conexión
Ejecución de una aplicación SQLJ
Motivación
?Dos tipos de usuario:? ocasionales: utilizan SQL interactivo para recuperar datos? desarrolladores: utilizan SQL embebido para tratamiento de datos
?Requisitos del tratamiento de datos?modificar/recuperar tuplas ? SQL
? capacidad de cálculo + instrucciones de control ? COBOL, C
?Por tanto, el tratamiento de datos requiere utilizar SQL dentro de un lenguaje de programación
SQL embebido
?Estándar para la inclusión de instrucción SQL dentro de un lenguaje de programación
?Se “extiende” el leng. prog. mediante la pre-compilación
?Toda instrucción SQL aparece precedida por una palabra clave reconocida durante la pre-compilación
?Para el caso de JAVA?estándar SQLJ
SQLJ
? Interfaz de alto nivel: consultas directamente en SQL?Análisis sintáctico y semántico en tiempo de
(pre)compilación? Interoperabilidad: estándar ANSI (diciembre, 1998)
Pre-compilador SQLJ• comprobación de sintaxis• comprobación de tipos• comprobación de esquema
Compilador Java
Código byte: Java + llamadas al controlador JDBC
Código fuente: Java + JDBC
Código fuente: Java + SQLJ.....
#sql [contexto conexión] {select ...};
Controlador JDBC
SistemaBase de Datos
>>sqlj mifichero.sqlj
>>javac mifichero.java
>>java mifichero.class
Pasos para la ejecución de una aplicación .sqlj
Desarrollo de Bases de Datos
Oscar Díaz - Facultad de Informática - Universidad del País Vasco / Euskal HerrikoUnibertsitatea
?Variables de Java que aparecen en sentencias SQL
void ejemplo() throws Exception {
String cuentaA = null;String cuentaB = null;Integer elSaldo = null;DefaultContext contexto1 = new DefaultContext (
“jdbc:oracle:oci8:@midb”, “unusuario”, “secreto”, false );
#sql [contexto1] {select saldo INTO :elSaldofrom cuentaCorriente where codigo = :cuentaA};
#sql [contexto1] {update cuentaCorrienteset saldo = saldo + :elSaldo where codigo = :cuentaB};
Utilización de variables compartidas Cont.
?OJO: Identificadores de SQL no son sensibles. Identificadores de Java sí son sensibles
#sql [ctx] {update Alumno set nota= :la_nota where dni = :el_dni}
#sql [ctx1] {select nombre into :el_nombre from Alumno where dni = :el_dni}
Las variables compartidas precedidas por “ :”
contexto en el que seejecuta la sentencia SQL
instrucción SQLJ
Compatibilidad de tipo SQL ? Java
Tipos Java (escalares)
Tipos SQL
boolean BIT byte TINYINT short SMALLINT int INTEGER long BIGINT float REAL double FLOAT, DOUBLE
#sql [ctx] {update Alumno set nota= :la_nota where dni = :el_dni}? A la variable de SQL “nota” se le asigna la variable JAVA
“la_nota”? sus tipos tienen que ser compatibles
El valor null
Tipos Java (clases wrapper)
Tipos SQL
java.lang.Boolean BIT java.lang.Byte TINYINT java.lang.Short SMALLINT java.lang.Integer INTEGER java.lang.Long BIGINT java.lang.Float REAL java.lang.Double FLOAT, DOUBLE java.lang.String CHAR, VARCHAR,
LONGVARCHAR java.math.BigDecimal NUMERIC, DECIMAL byte[ ] BINARY, VARBINARY,
LONGBINARY java.sql.Date DATE java.sql.Time TIME java.sql.Timestamp TIMESTAMP
? SQLJ define para cada clase escalar de Java, una clase “wrapper” donde? se soporta el valor “null”? existe un método xxxValue que
permite la conversión al tipo primitivo (p.ej intValue pasa a int)
? otros métodos: toString(int), valueOf(String), shortValue()
? Nótese que si el tipo es wrapper empieza por mayúscula
Los tipos de datos de Java NO soportan el valor null.
•Recuperar null de SQL en Java
• Si una variable de tipo primitivo recibe null se genera el error SQLNullException
cont.
?Pasar null de Java a SQL
String elNombre = null;Short laEdad = null;#sql {insert into Alumno (dni, nombre, edad)
values (444, :elNombre, : laEdad)};
Short elDni;Short laEdad;#sql {select edad into :laEdad
from Alumno where dni = :elDni}short auxEdad = laEdad.shortValue(); error
Recuperación de datos
?Si SELECT devuelve un solo valor. ?El resultado se guarda en una variable del lenguaje anfitrión
#sql {SELECT edad INTO :laEdadFROM Alumno where dni = :elDni}
?Si SELECT devuelve un conjunto de valores. ?El resultado se guarda en un CURSOR
Desarrollo de Bases de Datos
Oscar Díaz - Facultad de Informática - Universidad del País Vasco / Euskal HerrikoUnibertsitatea
Cursores identificados por posición? Un cursor es un objeto de la clase “iterator”? El nº de columnas es igual al de la pregunta? Se especifica el tipo de los atributos de la pregunta
#sql public iterator iteAlumno (Integer, String); // 1.- define el tipo “iteAlumno”iteAlumno unCursor; // 2.- se introduce variable de este tipoInteger elDni; String elNombre;
#sql unCursor = {select dni, nombre from Alumno}; // 3.- se abre el cursorwhile (true) { // 4.- se itera sobre el cursor
#sql {fetch :unCursor into :elDni, :elNombre};if (un_cursor.endFetch()) break; // true si no hay más tuplasSystem.out.println (elDni, elNombre); }
un_cursor.close(); // 4.- se cierra el cursor
Cursores identificados por el nombre (recomendado)
? Un iterador especifica el nombre y tipo de los atributos de la pregunta? Los valores de los atributos del registro se obtienen con métodos con
nombre el del atributo
#sql public iterator iteAlumno (Integer el_dni, String el_nombre);iteAlumno unCursor; // variable de tipo la clase anteriorInteger elDni; String elNombre;#sql unCursor = {select nombre as el_nombre,
dni as el_dni from Alumno}; // asignación cjto. tuplaswhile (unCursor.next()) { // avanza a la sgte. tupla. ( false, si no hay más)
elDni = unCursor.el_dni(); // obtiene el valor del atributo de la tuplaelNombre = unCursor.el_nombre();System.out.println (elDni, elNombre);}
unCursor.close(); // liberación del recurso
Tratamiento de excepciones
?Excepción? es un objeto de tipo SQLException? se crea cuando se produce una excepción?métodos: getMessage, getErrorCode, getSQLState
try{ #sql {select nombre into :elNombre from Alumno where dni = :elDni};}
catch( SQLNullException ne ){
System.out.println(“ Se ha encontrado un valor null: “ + ne. getErrorCode());}
catch( SQLException e ){
System.out.println(“ Error: ” + e.getMessage() + e.getErrorCode());}
Contexto de conexión
? Una instrucción SQL se ejecuta en un contexto de conexión? #sql [contexto] {update Alumno set nota= :la_notawhere dni = :el_dni}
? Este contexto indica ? el SGBD, ? la base de datos? usuario y password?modo “autocommit”
con el que se ejecutará la instrucción SQL
? Este contexto se define como una instancia de la clase sqlj.runtime.DefaultContext
Clase DefaultContext
? static DefaultContext DefaultContext(java.lang.String url, java.lang.String user, java.lang.String password, booleanautoCommit) ? Crea el contexto por defecto
? static DefaultContext getDefaultContext()? Devuelve el contexto por defecto
? static void setDefaultContext(DefaultContext ctx)? Establece el contexto por defecto
? public void close()? Cierra el actual contexto
Ejemplo
DefaultContext miEjemplo = new DefaultContext (“jdbc:oracle:oci8:@midb”, “unusuario”, “secreto”, false );
DefaultContext.setDefaultContext ( miEjemplo );
#sql [miEjemplo] {update ...}; //no sería necesario poner el contexto
miEjemplo.close();
Desarrollo de Bases de Datos
Oscar Díaz - Facultad de Informática - Universidad del País Vasco / Euskal HerrikoUnibertsitatea
Varios contextos de conexión simultáneos? Necesidad de usar en la aplicación SGBDs distintos? Necesidad de usar BD diferentes? Necesidad de añadir más funcionalidades a la clase contexto de conexión
DefaultContext miEjemplo = new DefaultContext (“ jdbc:oracle:oci8:@midb”, “unusuario”, “secreto”, false );
DefaultContext otroEjemplo = new DefaultContext (“ jdbc:oracle:oci8:@midb”, “otrousuario”, “ misecreto”, false );
DefaultContext.setDefaultContext ( miEjemplo );
#sql {select ...}; // utiliza el contexto por defecto
#sql [otroEjemplo] {update ...};
miEjemplo.close(); otroEjemplo.close( );
Contexto de ejecución? Una instrucción SQL se ejecuta en un contexto de ejecución:#sql [unCtxCon, unCtxEje] {update Alumno set nota = nota + 1 where curso = 5};
? Este contexto es una zona compartida por el runtime del SGBD y el programa, para intercambiar información sobre ?MaxRows : máximo nº de tuplas que puede guardar un cursor?MaxFieldSize: máximo nº de bytes de un atributo?QueryTimeout: segundos de espera a una sentencia SQL?UpdateCount: nº tuplas afectadas con última sentencia SQL? SQLWarnings : texto error generado en la ejecución
? Estos atributos se guardan como una instancia de la clase sqlj.runtime.ExecutionContext
// Crea un contexto de ejecución donde guarda las incidenciasExecutionContext unCtxEje = new ExecutionContext();
#sql [unCtxCon, unCtxEje] {delete from Alumno where curso = 5};
System.out.println(“Se han borrado” + unCtxEje.getUpdateCount() + “ alumnos”);
// Espera 3 segundos a que se ejecute la sentencia SQLunCtxEje.setQueryTimeout(3);
#sql [unCtxCon, unCtxEje] {update Alumno set curso = 5};
Ejemplo
Pre-compilador SQLJ• comprobación de sintaxis• comprobación de tipos• comprobación de esquema
Compilador Java
Código byte: Java + llamadas al controlador JDBC
Código fuente: Java + JDBC
Código fuente: Java + SQLJ.....
#sql [contexto conexión] {select ...};
Controlador JDBC
SistemaBase de Datos
>>sqlj mifichero.sqlj
>>javac mifichero.java
>>java mifichero.class
Tratamiento fichero .sqlj
Configuración de la pre-compilación?Algunos parámetros de configuración? dir : directorio de los ficheros .java generados? user y password : nombre de usuario, y su clave, para conectarse a
la bd. (si no es null, el sistema realiza comprobación online)? url: indica dónde establecer la conexión ? driver: controladores JDBC? offline/online: comprobación sin/con conexión a la bd.
?Pueden indicarse?explícitamente:
>> sqlj -user=unusuario -password=secreto mifichero.sqlj
?en el fichero sqlj.properties, consultado al invocar a sqljsqlj.user=unusuariosqlj.password=secreto
Conexión durante la pre-compilación
miE
jempl
o
otroEjemplo
Conexiones en la ejecución
mifichero.sqlj SQLJ mifichero.javaCompilador
Javamifichero.class
Conexiones en la compilación
Desarrollo de Bases de Datos
Oscar Díaz - Facultad de Informática - Universidad del País Vasco / Euskal HerrikoUnibertsitatea
public class top5 {#sql static iterator top5It (String unAlumno, Integer notaMedia);
void listarTop5() throws Exception {
top5It losTop5;String elAlumno = null;Integer laNotaMedia = null;int contador = 0;
#sql losTop5 = { SELECT elAlumno AS unAlumno, avg(nota) AS notaMediaFROM AluAsiGROUP BY elAlumnoORDER BY 2 DESC};
System.out.println("ALUMNO " + "SU NOTA MEDIA");while (losTop5.next() && contador < 5) {
elAlumno = losTop5.unAlumno();laNotaMedia = losTop5.notaMedia();System.out.println(elAlumno + " " + laNotaMedia);contador = contador + 1;
}losTop5.close();}
top5() {ConnectionManager.initContext();}}
Ejercicio
? La casa discográfica VIRGIN desea crear una base de datos sobre las canciones, los autores y los cantantes que hacen distintas versiones de dichas canciones. Un autor puede componer distintas canciones y una canción puede tener distintos compositores (tabla Aut_Can).
? Por otro lado, los cantantes pueden realizar distintas versiones de una determinada canción. Las canciones están agrupadas en álbumes (tabla Can_Can_Al). En un álbum una misma canción puede ser cantada por distintos cantantes, pero un cantante no puede tener diferentes versiones de la misma canción en el mismo álbum. El diagrama E/R y las tablas correspondientes son estas:
Esquema
Autor
AUT_CAN CAN_CAN_AL
Canción
Cantante
Álbum
M
N M
N
P
Fecha
Duración
Esquema
?AUTOR (NomAut, Tfno, Cuota)?CANCION (Título, Estilo)?CANTANTE (NomCan, Tfno, País)?ALBUM (Código, DiscosPlatino)?AUT_CAN (ElAutor, LaCanción)?CAN_CAN_AL (LaCanción, ElCantante, ElAlbum,
Fecha, Duración)
Ejercicio 1
?Expresar en SQLJ un programa que cree un nuevo album recopilatorio con las canciones 1º) de cualquier estilo 2º) existan más de dos versiones de las mismas, y 3º) cuyos autores hayan compuesto alguna canción de estilo “Jazz”.?Expresar en SQLJ un programa que cree el album
“XXX The BEST” que contenga para cada autor sus 5 canciones de más éxito, es decir, aquellas que aparezcan en más álbumes.
Ejercicio 1
?Conseguir todas las canciones?Para cada canción?Comprobar que si es de algún autor de Jazz?Comprobar número de versiones?Si se cumplen las dos anteriores?Insertar en la BD (número de álbum y cantante fijos que
deberíamos saber)
Desarrollo de Bases de Datos
Oscar Díaz - Facultad de Informática - Universidad del País Vasco / Euskal HerrikoUnibertsitatea
Ejercicio 1
?Conseguir todas las canciones?Select titulo from cancion
?Comprobar que si es de algún autor de Jazz?Select 2
FROM AUT_CAN AS AC1 NJ Autor NJ AUT_CAN AS AC2 NJ Canción WHERE AC1.título=:título AND C2.Estilo=‘Jazz’?(si devuelve tuplas es que sí tiene autor de Jazz)
?Comprobar número de versiones?Select COUNT (Distinct Album) INTO :numversiones
from CAN-CAN-AL WHERE título=:titulo?(si >2, entonces insertar en la BD)
Otras opciones del lenguaje
?Borrar o modificar la tupla actual#sql [ctx] {delete from tabla
WHERE CURRENT OF :variableIteradoranfitrión};
#sql [ctx] {update tabla set atributo = valorWHERE CURRENT OF : variableIteradoranfitrión};
#sql iterator UnIterador(String, String);UnIterador iter; …#sql iter = {select nombre, dir from cliente where ciudad= ‘Donostia’};while (true) { #sql {fetch :iter into :nombre, :dir};
if (iter.endFetch()) break;System.out.println (nombre+ " " + dir + " ¿Borrar (S/N)?");entrada= new BufferedReader (new InputStreamReader (System.in));tecla = entrada.readLine();if (tecla.equals(“S"))
#sql {delete from cliente where current of :iter};}
Procedimientos almacenados
?Los definen los usuarios.?Son objetos del esquema?Se ejecutan en el SGBD?La sintaxis de las llamadas depende del SGBD. Por
ejemplo, en Oracle
#sql [ctx] { CALL procedimiento(:arg1, :arg2) };
#sql [ctx] var= { VALUES funcion(:arg1, :arg2) };
Transacción
?Comienzo de la transacción: ?Al realizar una operación SQL sobre tuplas de la BD
?El control de concurrencia se basa en reservas?A nivel de tupla
?Reserva de tupla: lo hace el sistema al escribir?Para leer no se hace reserva
?Liberar la reserva:?Automáticamente?Manualmente
#sql {commit};
#sql {rollback};
AutoCommit
AutoCommit
?Se puede definir cuando se crea el contexto de conexión:?Autocommit=false
?Las transacciones se deben terminar manualmente
?Autocommit=true
?Las transacciones se terminan automáticamente en cuantoterminan sus operaciones?NO hay posibilidad de hacer ROLLBACK
DefaultContext ctx1= new DefaultContext ( “jdbc:oracle:oci8:@mibd”, “Jon”, “secreto”, false);
DefaultContext ctx2= new DefaultContext ( “jdbc:oracle:oci8:@mibd”, “Nerea”, “asaber”, true);
Autocommit
?También se puede cambiar através del contexto de conexión:
Tiene que ser la primera operación de la transacciónctx.getConnection().setAutoCommit (true);
Desarrollo de Bases de Datos
Oscar Díaz - Facultad de Informática - Universidad del País Vasco / Euskal HerrikoUnibertsitatea
Recomendaciones para el diseño de transacciones
Reducir el tráfico de red#sql public iterator IteBDNotas(int nota); IteBDNotas bdNotas;...#sql bdNotas = {select nota from Matricula where codAlum = 787}; #sql media = {select avg(nota) from Matricula where codAlum = 787};while (bdNotas.next()) {
nota = bdNotas.nota(); ...if (nota > media) { System.out.println(... );}
}
#sql public iterator iteBDNotas (int nota); iteBDNotas bdNotas;... // Solo se obtienen las notas que son superiores a la media#sql bdNotas = {select nota from Matricula
where codAlum = 787 and nota > (select avg(nota) from Matricula where codAlum = 787 )}; while (bdNotas.next()) {
nota = bdNotas.nota(); ...System.out.println(... );
}
Reducir el tráfico de red. Row Prefetching
?El estándar JDBC trae las tuplas del resultado de una consulta de una en una?Para cada tupla hace falta un acceso a la BD
?Con la opción DefaultRowPrefetch las tuplas traidas sepueden agrupar?Se ahorran accesos a la BD?El valor por defecto es 10 (Oracle)?Se debe indicar el valor a cada instancia del contexto de
conexión
Reducir el tráfico de redRow prefetching
?Cambiar el valor por defecto a 20 tuplas en uncontexto concreto (ctx)
?Cambiarlo en el contexto por defecto((OracleConnection)DefaultContext.getDefaultContext().getConnection()).get
DefaultRowPrefetch()
((OracleConnection)DefaultContext.getDefaultContext().getConnection()).setDefaultRowPrefetch(20)
((OracleConnection)ctx.getConnection()).getDefaultRowPrefetch()
((OracleConnection)ctx.getConnection()).setDefaultRowPrefetch(20)
Reducir el tráfico de redUpdate batching
?Las operaciones UPDATE, DELETE, INSERT sepueden agrupar (en un proceso batch) para que la ejecución sea más rápida (ahorrando accesos a la BD)?Las instrucciones en modo batch deben ser del mismo
tipo
?Esta característica se aplica a cada contexto de ejecución
Reducir el tráfico de redUpdate batching
ExecutionContext ctxEje = new ExecutionContext(); ctxEje.setBatching(true);
ctxEje.setBatchLimit(limite); for (int j=1; i<=limite; i++) {
// meter las instrucciones en un “lote”#sql [ctxEje ] { INSERT INTO Tabla VALUES(:i) };
} //Ejecución explícita de todas las inserciones a la vez
int[ ] kop = ctxEje.executeBatch();
Desarrollo de Bases de Datos
Oscar Díaz - Facultad de Informática - Universidad del País Vasco / Euskal HerrikoUnibertsitatea
Reducir el tráfico de redUpdate batching
? las instrucciones de un lote se ejecutan de manera implícita: ?Antes de ejecutar una instrucción de otro tipo?Cuando se ejecuta commit?Cuando se llega al l ímite de instrucciones batch
?Otras instrucciones?ctxEje.isBatching()?ctxEje.getBatchLimit()?ctxEje.getBatchUpdateCounts()?ctxEje.cancel()
Reducir el tráfico de redUpdate batching
ExecutionContext ctxEje = new ExecutionContext (); ctxEje.setBatching(true); ctxEje.setBatchLimit(3);
#sql [ctxEje] {update Empleado set sueldo=sueldo+100 where dni=1};#sql [ctxEje] {update Empleado set sueldo=sueldo+100 where dni=2};
#sql [ctxEje] {update Empleado set sueldo=sueldo+100 where dni=3}; #sql [ctxEje] {update Empleado set sueldo=sueldo+100 where dni=4};
#sql [ctxEje] {update Empleado set sueldo=sueldo+100 where dni=5};#sql [ctxEje] {update Empleado set sueldo=sueldo+100 where categoria=10}; #sql [ctxEje] {update Empleado set sueldo=sueldo+100 where categoria=20};
#sql [ctxEje] {commit}; #sql [ctxEje] {update Empleado set sueldo=sueldo+100 where categoria=20};
ctxEje.executeBatch
¿Cuántos lotes hay y cuándo se ejecutan?
Reducir el tráfico de redUpdate batching
ExecutionContext ctxEje = new ExecutionContext (); ctxEje.setBatching(true); ctxEje.setBatchLimit(3);
#sql [ctxEje] {update Empleado set sueldo=sueldo+100 where na=1};#sql [ctxEje] {update Empleado set sueldo=sueldo+100 where na=2};
#sql [ctxEje] {update Empleado set sueldo=sueldo+100 where na=3}; // llegado al límite#sql [ctxEje] {update Empleado set sueldo=sueldo+100 where na=4};
#sql [ctxEje] {update Empleado set sueldo=sueldo+100 where na=5};#sql [ctxEje] {update Empleado set sueldo=sueldo+100 where categoria=10}; // límite =3#sql [ctxEje] {update Empleado set sueldo=sueldo+100 where categoria=20};
#sql [ctxEje] {commit}; // se ha llegado ha terminado la transacción#sql [ctxEje] {update Empleado set sueldo=sueldo+100 where categoria=20};
ctxEje.executeBatch(); // petición de ejecución explícita
Niveles de aislamiento en transac.
?Priorizar transacciones?Es posible hacer operaciones de lectura y escritura?Cuando se compromete una transacción se liberan las
reservas (protocolo estricto de dos fases)?Garantizar la serialización empeora el nivel de
concurrencia ? Para mejorar la concurrencia se propone relajar las reglas definiendo niveles de aislamiento?Se pueden ejecutar concurrentemente las transacciones
que tienen distintos niveles de aislamiento
Niveles de aislamiento en transac.?Para definir las características de la transacción se
debe utilizar como primera instrucción:
set transaction
[read only | read write][isolation level [read uncommitted | read committed |
| repeatable read | serializable]]
[diagnostics size <valor>]
Read uncommited
?Solo operaciones de lectura?Recomendable solo para transacciones que tienen
funciones estadísticas
?Las transacciones (Tj) pueden leer datos sincomprometer?Puede aparecer el problema de la lectura sucia (dirty
read)
Desarrollo de Bases de Datos
Oscar Díaz - Facultad de Informática - Universidad del País Vasco / Euskal HerrikoUnibertsitatea
Read uncommitted (dirty read)
Transacción T2
#sql iterator MiIter(int numcta);#sql {set transaction
isolation level read uncommitted};MiIter iter;
#sql iter = {select numcta from cuentawhere saldo<0};
while (iter.next( )) {ctax = iter.numcta( ); mandar_carta(ctax);}
#sql {commit};
Transacción T1
...#sql {update cuenta
set saldo= saldo- :cantwhere numcta= :ctax};
... ?#sql {update cuenta
set saldo = saldo+ :cantwhere numcta= :ctay };
...if (...) # sql {rollback};
Transacción T2
Read commited
?La transacción (Tj) no puede leer ni escribir un datomodificado por otra transacción (Ti) hasta que éstese comprometa?Evita la lectura sucia (dirty read)
?La transacción Tk puede leer o modificar un datoleido antes por Tj antes de comprometerlo?Puede ocurrir el problema de la lectura irrepetible
(unrepeatable read)
Read committed(unrepeatable read)
Transacción T1
#sql iterator MiIter(int dni);#sql {set transaction
isolation level read committed};MiIter iter;#sql iter = {select dni from cuenta
where saldo> 10.000.000};...a = iter.dni( );
... ?#sql iter = {select dni from cuenta
where saldo> 10.000.000};...
Transacción T2
#sql {update cuentaset saldo= saldo - :cantwhere numcta= A2345};
#sql {commit};Transacción T2
Repeatable read
?Se aplica el protocolo de reserva de dos fases contodo?Se evita la lectura sucia (dirty read)?Se evita la lectura irrepetible (unrepeatable read)?Puede aparecer el problema de la modificación fantasma
cuando hay transacciones que introducen nuevas tuplas. Elpredicado no se tiene en cuenta
Repeatable read (ghost update)
Transacción T1
#sql iterator MiIter(int dni);#sql {set transaction
isolation level repeatable read};MiIter iter;#sql iter = {select dni from cuenta
where saldo> 10.000.000};...a = iter.dni( );... ?#sql iter = {select dni from cuenta
where saldo> 10.000.000};...
Transacción T2
#sql {insert into cuenta values(A2565, 37,12.000.000, ‘98-4-20’, 2, ‘Matia’)};
#sql {commit};
Transacción T2
Serializable
?Se evita la lectura sucia?Se evita la lectura irrepetible?Se evita la modificación fantasma?En el grafo de prioridad, también se almacena
información acerca de los predicados utilizados?En oracle se usan rollback segments y marcas de tiempo
?Consistencia a nivel de transacción: los datosutilizados a lo largo de la transacción, son loscomprometidos al comienzo de la misma.
Desarrollo de Bases de Datos
Oscar Díaz - Facultad de Informática - Universidad del País Vasco / Euskal HerrikoUnibertsitatea
Serializable
Transacción T1
update cuenta set saldo= saldo * 2 where numcta= 2
update cuenta set saldo = saldo + 30 where numcta = 3select * from cuentaupdate cuenta set saldo = saldo + 30 where numcta = 2
Error de pérdida de la serialización: ORA-08177
Transacción T2set transaction isolation level serializableupdate cuenta set saldo = saldo + 20 where numcta= 1insert into cuenta values (4, …)select * from cuenta
commit
Niveles de aislamiento. Resumen
Reserva de exclusión larga sobre las tuplas
Reservacompartida larga sobre las tuplas
Reservas de exc., compart. y sobrepredicados largas
Read uncommited NO NO
Read commited SI NO NO
Repeatable read SI SI NO
Serializable SI SI NO
Reserva larga = al comprometerse la transacción se libera la reserva (vs se libera la reserva nada más terminar de usar el dato)
No todos los SGBD ofrecen todos los niveles de aislamiento
Oracle: Read committed, Serializable
DB2: Read uncommited, Read commited, repeatableread & serializable
Reservas explícitasLOCK TABLE
?Sintaxis:
?Reserva explícita de una tabla completa?Sin NOWAIT la transacción se queda en espera
hasta lograr la reserva
LOCK TABLE Tabla/Vista IN modo -reserva MODE [NOWAIT]
Modos de reserva ClaveOtras reservascompatibles
Consistencia nivel de transacción
ROW SHARE IS IS, IX, S, SIX ?
ROW EXCLUSIVE IX IS, IX ?
SHARE S IS, S ?
SHARE ROW EXCLUSIVE SIX IS ?
EXCLUSIVE X -- ?
Reservas explícitasSELECT…FOR UPDATE
? Sintaxis:
? Nivel de consistencia de transacciones? Las tuplas encontradas se reservan una a una, pero todas a la vez y
en modo exclusivo? Si una tupla ya está reservada
? Con NOWAIT? Se envía un mensaje de error al momento? Sin NOWAIT? La transacción se queda en espera hasta que se libera la reserva
? Si es en un iterador al llenarlo se reservan las tuplas (y no cuando se hacenext)? Para liberar la reserva, se espera al commit o al rollback (y no cuando se acaba
de trabajar con el iterador)
? No se pueden utilizar: funciones agregadas, la cláusula group by, ni distinct
? Se pueden reservar varias tablas de una consulta con Join
SELECT … FOR UPDATE [OF tabla] [NOWAIT]
SELECT ... FOR UPDATE. Ejemplo
#sql libres = {select asientos from espectaculo where cod = 34 }System.out.println (libres + “ asientos disponibles. “+
”¿Cuántas entradas quiere?”);cant = entrada.readLine( );if (cant<= libres)
#sql {update espectáculoset asientos = asientos - :cant where cod = 34};
else { … }#sql {commit};
for update
select nombre, saldofrom cuenta natural join clientewhere ciudad= ‘Durango’for update of Cuenta
Reserva las cuentas de los clientes de Durango
Definición y verificación de restricciones
? Not Deferrable (No diferible)? La comprobación de la restricción se realiza cada vez que se ejecuta una
sentencia SQL en la transacción.
? Deferrable (Diferible)? La comprobación de la restricción se puede diferir hasta el punto en el
que se compromete la transacción
? initially deferred, initially immediate : ? Se indica cuándo se realizará la comprobación de las restricciones
diferibles? Initially immediate
? Se comprueba cada vez que se ejecuta una sentencia SQL
CONSTRAINT nombre-restricción ...[NOT] DEFERRABLE [INITIALLY [DEFERRED | IMMEDIATE] ]
Desarrollo de Bases de Datos
Oscar Díaz - Facultad de Informática - Universidad del País Vasco / Euskal HerrikoUnibertsitatea
Cambio de las definiciones de restricciones
? En general las restricciones serán diferibles? La comprobación de las restricciones diferidas se retrasa
hasta que se haga explícito #sql {set ... immediate} o hastacomprometer la transacción.
?Al comprometer una transacción que tiene lasrestricciones diferidas, el sistema las pasa al estadoimmediate y se hace la comprobación.?Si se viola una restricción, se termina la transacción (rollback) y
se envía un mensaje de error
SET CONSTRAINTS [ALL | murriztapen_izena {, urriztapen_izena}][DEFERRED | IMMEDIATE]
Restricciones. Ejemplos
#sql {insert into alumno values (23, …)};...#sql {commit};
create table alumno(…constraint matriculado check dni in (select dni from matricula) not deferrable)
commitinsert ...
create table alumno(…constraint matriculado check dni in (select dni from matricula) deferrable initially immediate )
commitinsert ...
Restricciones. Ejemplos
#sql {insert into alumno values (23, …)};...#sql {commit};
create table alumno(…constraint matriculado check dni in (select dni from matricula) deferrable initially deferred )
set constraint …immediate
commitinsert ...
commitinsert ...