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<hmira...@gmail.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
>> <hmira...@gmail.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@postgresql.org <mailto:pgsql-es-ayuda@postgresql.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@postgresql.org
> )
> Para cambiar tu suscripción:
> http://www.postgresql.org/mailpref/pgsql-es-ayuda
>

Responder a