Nivel de aislamiento y concurrencía

From: mauricio pullabuestan <jmauriciopb(at)yahoo(dot)es>
To: PostgreSQL Lista Castellano <pgsql-es-ayuda(at)postgresql(dot)org>
Subject: Nivel de aislamiento y concurrencía
Date: 2015-09-08 02:48:53
Message-ID: 1150148725.4225814.1441680534018.JavaMail.yahoo@mail.yahoo.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-es-ayuda

Buen día.

Tengo una función que devuelve el próximo número secuencialpara mis documentos, los cuales no pueden tener gaps ni overlaps

CREATE OR REPLACEFUNCTION prbsecuencia.movimiento_id(v_movimiento_id integer)

  RETURNS integer AS

$BODY$

Declare v_key_newinteger;

Begin

Update prbsecuencia.secuencia

 Set secuencia = secuencia + 1

 Where movimiento_id =v_movimiento_id

 RETURNING secuencia INTO v_key_new;

  IF NOT FOUND THEN

    Insert Into prbsecuencia.secuencia Values (v_movimiento_id,1) RETURNING 1 INTO v_key_new;

END IF;

 Return v_key_new;

 

end; $BODY$

  LANGUAGE plpgsql VOLATILE

  COST 100;

ALTER FUNCTION prbsecuencia.movimiento_id(integer)

  OWNER TO postgres;

 
Entonces desde mi aplicación hago:

 
Begin transaction

   Select nuevo_id From prbsecuencia.movimiento_id(10)t (nuevo_i)

 
  insert a la tabla cabecera, detalle y una par de tablas más.

 
Commit

 
Si falla la transacción hago un Rollback.

 
Mis conocimientos en postgresql son básicos, tengo entendido que elnivel de aislamiento por default en Postgresql es Read Committed, según elnivel de aislamiento y la función no debería tener problemas, para probar hiceuna pequeña aplicación con un

for de 1 a 20000

1.- Comienza una transacción

2.- Recupera el próximo secuencial

3.- Inserta datos a un par de tablas

4.- termina la transacción

Next

 
Instancie 4  veces la aplicacióny corrí la aplicación todo iba bien hasta más o menos 9000 interacciones decada instancia entonces se produjo un bloqueo en la cuarta instancia, tuve quematar la instancia y las otras 3 instancias pudieron acabar el proceso, todoresulto como esperaba, todas la instancias obtuvieron el número correspondienteno hubo Gaps y overlaps.

 
La duda porque se dio el bloqueo?

 
Con postgresql basta con el nivel de aislamiento por default para garantizar ladistribución correcta o se puede reforzar, como con Sql Server utilizo hints.

 
Como podría hacer para que desde una función llamar a la función  prbsecuencia.movimiento_id() con 2 parametros, el id de movimiento y una variable,dentro de la función se le asigne el próximo número de secuencia a la variablepara luego usar la variable ya con el valor correspondiente algo así:

 
CREATE OR REPLACE FUNCTION prbsecuencia.movimiento(parametro1 integer, parametro2integer)

  RETURNS Boolean AS

$BODY$

Declare key_newinteger;

Begin

 
Select * From prbsecuencia.movimiento_id(10,key_new);

 Insert Into cabecera (campo1, campo2, campo3) Values(key_new, ‘valor1’,valor2);

 
Insert Into detalle (camp1,campo2, campo3) Values(key_new, ‘a’, ‘b’)

 Return true;

 

end;

$BODY$

  LANGUAGE plpgsql VOLATILE

  COST 100;

 Por lo que entiendo con el default Read Committed esto en un ambiente multiusuarioy con una alta concurrencia no debería tener problemas, si los tuvieran cual esla manera correcta de hacerlo.

 

 
Saludos,

Mauricio 

Responses

Browse pgsql-es-ayuda by date

  From Date Subject
Next Message Horacio Miranda 2015-09-08 03:01:41 Re: Nivel de aislamiento y concurrencía
Previous Message Alvaro Herrera 2015-09-07 19:59:55 Re: Migracion de Sybase ASE a Postgres