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
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 |