Concurrencia y transacciones - script - ejemplo

From Ibbddunq

Revision as of 16:32, 11 November 2009 by Carlos (Talk | contribs)
(diff) ←Older revision | view current revision (diff) | Newer revision→ (diff)

Contents

El esquema de BD

  encomienda <nroEncomienda, cliente, peso>
  servicio <nroServicio, origen, destino, disponible, cargaTotal>
  encomiendaEnServicio <nroServicio, nroEncomienda>
  

agregarEncomienda

  procedure agregarEncomienda(elCliente, elPeso, elServicio)
  begin
    declare nroNuevaEnco integer;
    declare disponibleNuevo integer;
    declare cantEncomiendas integer;
    
    select max(nroEncomienda) + 1 from encomienda into nroNuevaEnco;
    select disponible - elPeso from servicio
     where nroServicio = elServicio
      into disponibleNuevo;
    select count(*) from encomiendaEnServicio where nroServicio = elServicio
      into cantEncomiendas;
    
    if (cantEncomiendas < 10) then
        insert into encomienda (nroEncomienda, cliente, peso)
        values (nroNuevaEnco, elCliente, elPeso);
        insert into encomiendaEnServicio (nroEncomienda, nroServicio)
        values (nroNuevaEnco, elServicio);
        update servicio set disponible = disponibleNuevo
         where nroServicio = elServicio;
    end if;
  end
  

con este stored procedure se puede

  • mostrar un schedule de dos tx en el que el disponible de un servicio quede mal.
  • llegar a la conclusión de qué condición deben tener dos ejecuciones concurrentes para que pueda haber anomalías de concurrencia: que estén agregando encomiendas en el mismo servicio.
  • ver cómo tiene que ser un schedule para ser "malo": ambos deben leer el disponibleNuevo antes de que cualquiera de ellos haga update.
  • tal vez,
    • corregir el update seteando disponible - elPeso, y sacando el select del servicio de arriba. Aclarar que toma el disponible en el momento que se ejecuta el update. Llegar a la conclusión de que se arregla la anomalía observada antes ...
    • ... pero queda otra: puedo poner 11 encomiendas en un servicio. Esta la vamos a tener que solucionar reservando un recurso, o sea, que sea válido que yo diga "yo agarro un servicio y hasta que yo no termine nadie puede hacer nada con el servicio"


pasarPeso

   procedure pasarPeso (servDesde, servHacia, cuanto)
   begin
     declare nuevoDisponible;
   
     start transaction
     update servicio set disponible = disponible + cuanto 
      where nroServicio = servDesde;
     select disponible - cuanto from servicio 
      where nroServicio = servHacia
       into nuevoDisponible;
     
     if (nuevoDisponible >= 0) then
         update servicio set disponible = disponible - cuanto
          where nroServicio = servHacia;
         commit;
     else
         rollback;
     end if;
   end


cantidadServiciosADestinos

ya viene ...

Personal tools