Practica3 - Apartado 5

De FdIwiki ABD
Saltar a: navegación, buscar

APARTADO 5.-

Para entregar: las instrucciones ejecutadas para cada paso: En la BDejemplo estamos haciendo una prueba con una compra nueva que queremos procesar con los siguientes valores de sus atributos de la tabla COMPRAS: ('00000003', '30000002',111, 0501,'sesion 1',1)

No tenemos que hacer un insert al principio. Seguimos los pasos:

0.- Como es un proceso nocturno de todas las compras del día, queremos bloquear toda la Tabla Compras para que nadie pueda modificarla, con un Lock explícito exclusivo. Esta operación puede ralentizar la BD haciendo esperar a otras transacciones, pero como es nocturno no nos preocupa y hará nuestro proceso más rápido.

LOCK TABLE COMPRAS IN EXCLUSIVE MODE;

1.- Comprobar que tiene saldo (en tabla TieneT) la tarjeta con la que se va a pagar. Mientras se hace la comprobación no queremos que nadie pueda consultar ni actualizar esa tarjeta, así que la bloqueamos usando una select . . . for update;

SELECT SALDO

FROM TIENET

WHERE DNI = '00000003' AND NUMT ='30000002'

for update;

2.- Si el saldo de la tarjeta es mayor o igual a la compra, entonces: - Creamos una fila en la tabla Compras con los valores de la compra Para ello usamos INSERT . . . .where 111 < (select saldo …);

INSERT INTO COMPRAS(dni, numt, numf, fecha, tienda, importe)

SELECT '00000003', 30000002, 111, 0501, 'sesion 1', 1

FROM COMPRAS C

where C.DNI = '00000003' AND C.NUMT = 30000002 AND

C.IMPORTE <= ( SELECT SALDO FROM TIENET T WHERE T.NUMT = 30000002 AND T.DNI = '00000003')

3.- Desbloqueamos la tarjeta y la tabla compras.

COMMIT;


4.- Comprueba que realmente se ha bloqueado lo que se ha pedido: abre dos sesiones y ejecuta las instrucciones necesarias para comprobarlo.


Sesión 1


set transaction isolation level serializable;

set autocommit off;


Sesión 2

commit;

set transaction isolation level serializable;

set autocommit off;


Sesión 1


LOCK TABLE COMPRAS IN EXCLUSIVE MODE;


SELECT SALDO

FROM TIENET

WHERE DNI = '00000003' AND NUMT ='30000002'

for update;


Sesión 2

INSERT INTO COMPRAS(dni, numt, numf, fecha, tienda, importe)

SELECT '00000003', 30000002, 111, 0501, 'sesion 1', 1

FROM COMPRAS C

where C.DNI = '00000003' AND C.NUMT = 30000002 AND

C.IMPORTE <= ( SELECT SALDO FROM TIENET T WHERE T.NUMT = 30000002 AND T.DNI = '00000003')


Tambien podemos comprobar este bloqueo mediante un Update:

update TieneT

set saldo = saldo - 1

where dni = '00000003' and numt ='30000002';


Comprobamos que la sesion 2 no puede actualizar esa fila porque la sesion 1 ha hecho un select...for update bloquando la fila hasta que haga commit.

--Kevin (discusión) 19:07 20 abr 2015 (CEST)