Re: [pgsql-es-ayuda] Nivel de aislamiento y concurrencía

From: "Hector R(dot) De los Santos " <zahory(at)gmail(dot)com>
To: mauricio pullabuestan <jmauriciopb(at)yahoo(dot)es>
Cc: PostgreSQL Lista Castellano <pgsql-es-ayuda(at)postgresql(dot)org>
Subject: Re: [pgsql-es-ayuda] Nivel de aislamiento y concurrencía
Date: 2015-09-09 15:44:16
Message-ID: CALX2jtARYoiapwbLze_FoL=j4+ECxN-iR40NoaCkzkFCXPPM4A@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-es-ayuda

Mauricio:
Como dato aclaratorio, en PostgreSQL todo lo que pongas dentro de una
función se ejecuta en una transacción de forma automatica.

Saludos,

:: HDS Consultores TI
Servidores | Redes | Programacion | GNU/Linux | PostgreSQL
Web: http://hdsconsultores.net
Blog: http://codigohds.com
Linux User #:320363

El 8 de septiembre de 2015, 8:48 p. m., Horacio Miranda<hmiranda(at)gmail(dot)com>
escribió:

>
> On 9/9/2015 12:20 PM, mauricio pullabuestan wrote:
>
>> Hola Horacio.
>>
>> Gracias por responder
>>
>> Justamente estoy probando la mejor alternativa para hacer una función
>> que dispense correlativos, para toda la aplicación.
>>
>>
> Para gran volumen de concurrencia, un motor ( job que corre cada segundo o
> tiempo X que hace los updates es lo mejor ).
>
> 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.
>>
>
> Hay dos cosas,
>
> A.- Por defecto postgres es read Committed ,
> http://www.postgresql.org/docs/9.1/static/transaction-iso.html
>
> 13.2.1. Read Committed Isolation Level
>
> Read Committed is the default isolation level in PostgreSQL
>
> B.- El tipo de Lock,
> http://www.postgresql.org/docs/9.1/static/explicit-locking.html
>
> The commands UPDATE, DELETE, and INSERT acquire this lock mode on the
> target table (in addition to ACCESS SHARE locks on any other referenced
> tables). In general, this lock mode will be acquired by any command that
> modifies data in a table.
>
>
>> En caso de ser bloqueo diferente a registro seria perjudicial tener una
>> sola tabla que tenga los correlativos?
>>
>>
> Depende de tu modelo de datos, pero en general puedes usar sequencias (
> ojo, las secuencias se usan se haga commit o rollback, tener el dato en una
> tabla es super util ( pero el proceso que se encarga de asignar numero del
> registro debe ser un proceso unico ).
>
> 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 <mailto:pgsql-es-ayuda(at)postgresql(dot)org>)
>> Para cambiar tu suscripci�:
>> http://www.postgresql.org/mailpref/pgsql-es-ayuda
>>
>>
>>
>>
> -
> Enviado a la lista de correo pgsql-es-ayuda (pgsql-es-ayuda(at)postgresql(dot)org
> )
> Para cambiar tu suscripción:
> http://www.postgresql.org/mailpref/pgsql-es-ayuda
>

In response to

Browse pgsql-es-ayuda by date

  From Date Subject
Next Message Wilfredo Patricio Castillo 2015-09-10 03:21:22 Requerimientos mínimos para instalar en windows como en Linux
Previous Message Horacio Miranda 2015-09-09 00:48:50 Re: Nivel de aislamiento y concurrencía