Re: Nivel de aislamiento y concurrencía

From: mauricio pullabuestan <jmauriciopb(at)yahoo(dot)es>
To: Horacio Miranda <hmiranda(at)gmail(dot)com>, PostgreSQL Lista Castellano <pgsql-es-ayuda(at)postgresql(dot)org>
Subject: Re: Nivel de aislamiento y concurrencía
Date: 2015-09-09 00:20:21
Message-ID: 1330939134.5009309.1441758021470.JavaMail.yahoo@mail.yahoo.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-es-ayuda

Hola Horacio.
Gracias por responder
Justamente estoy probando la mejor alternativa para hacer una función que dispense correlativos, para toda la aplicación.
Una pregunta, cuando hago un update mitabla set secuencia = secuencia + 1 where id = 12 dentro de una transacción y con Read Committed, que tipo de bloqueo se aplica? por registro, por pagina o tabla teniendo en cuenta que la tabla es pequeña de no mas de 200 registros.
En caso de ser bloqueo diferente a registro seria perjudicial tener una sola tabla que tenga los correlativos?
Saludos.Mauricio

 Mauricio. Cuenca-Ecuador

El Lunes 7 de septiembre de 2015 22:02, Horacio Miranda <hmiranda(at)gmail(dot)com> escribió:

En mi experiencia, deberías tener un proceso ( único proceso que asigne
folios a tus documentos ).

muchos procesos pueden insertar datos, pero solo un proceso debiera ser
el encargado de asignar esos folios. ( cuando era DBA para el registro
civil de Chile ) fue la única forma de garantizar que los bloqueos se
mantuvieran al mínimo.

Puedo estar equivocado, pero bajo mucho trafico la aplicación no se
bloquea y los números de documentos son correlativos.

Es posible para tu aplicación usar esa lógica ?

On 9/8/2015 2:48 PM, mauricio pullabuestan wrote:
> Buen día.
>
> Tengo una función que devuelve el próximo número secuencial para mis
> documentos, los cuales no pueden tener gaps ni overlaps
>
> CREATE OR REPLACE FUNCTION prbsecuencia.movimiento_id(v_movimiento_id
> integer)
>    RETURNS integer AS
> $BODY$
> Declare v_key_new integer;
> 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 el
> nivel de aislamiento por default en Postgresql es Read Committed, según
> el nivel de aislamiento y la función no debería tener problemas, para
> probar hice una 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ón y corrí la aplicación todo iba bien
> hasta más o menos 9000 interacciones de cada instancia entonces se
> produjo un bloqueo en la cuarta instancia, tuve que matar la instancia y
> las otras 3 instancias pudieron acabar el proceso, todo resulto como
> esperaba, todas la instancias obtuvieron el número correspondiente no
> hubo Gaps y overlaps.
> La duda porque se dio el bloqueo?
> Con postgresql basta con el nivel de aislamiento por default para
> garantizar la distribució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 variable para luego usar la variable ya con el valor
> correspondiente algo así:
> CREATE OR REPLACE FUNCTION prbsecuencia.movimiento(parametro1 integer,
> parametro2 integer)
>    RETURNS Boolean AS
> $BODY$
> Declare key_new integer;
> 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
> multiusuario y con una alta concurrencia no debería tener problemas, si
> los tuvieran cual es la manera correcta de hacerlo.
> Saludos,
> Mauricio

-
Enviado a la lista de correo pgsql-es-ayuda (pgsql-es-ayuda(at)postgresql(dot)org)
Para cambiar tu suscripci�:
http://www.postgresql.org/mailpref/pgsql-es-ayuda

In response to

Responses

Browse pgsql-es-ayuda by date

  From Date Subject
Next Message Horacio Miranda 2015-09-09 00:48:50 Re: Nivel de aislamiento y concurrencía
Previous Message Edwin Quijada 2015-09-08 15:27:30 RE: Migracion de Sybase ASE a Postgres