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 >