Re: obtener el valor de una secuencia sin hacer antes nextval()

From: Alvaro Herrera <alvherre(at)commandprompt(dot)com>
To: Juan Martínez <jeugenio(at)umcervantes(dot)cl>
Cc: Raul Caso <feve18(at)gmail(dot)com>, lista postgresql <pgsql-es-ayuda(at)postgresql(dot)org>
Subject: Re: obtener el valor de una secuencia sin hacer antes nextval()
Date: 2006-02-24 02:50:24
Message-ID: 20060224025024.GB9837@surnet.cl
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-es-ayuda

Juan Martínez escribió:
> > Juan Martínez escribió:

> Francamente creo que te debes relajar y no hacer prevalecer como correctas
> tus formas de resolver problemas. Puede que estes en lo correcto, pero hay
> más de una forma siempre de hacer las cosas.

:-) Cierto, estaba un poco exaltado. Pero mantengo mi opinion de que
lo que proponias no soluciona realmente el problema.

> > de olvidarte de las secuencias y usar un objeto que
> > impide concurrencia (LOCK TABLE o SELECT FOR UPDATE). Estas usando un
> > martillo para poner un tornillo, pero como no entra facilmente le
> > inventas un tirabuzon con resorte para que el tornillo reciba el golpe
> > en "diagonal". Es muchismo mas sencillo usar el atornillador.
>
> Creo que sigues descontextualizando mis sugerencias.

Pensemos en el problema puntual de generar numeros de folio. Los
numeros de folio tienen una caracteristica muy particular: deben ser
unicos y ser asignados correlativamente. Es muy raro que sea aceptado
que hayan "hoyos" en la asignacion de numeros de folio.

Hay varias maneras de evitar los hoyos, como tu dices: por ej. que sean
generados por una sola persona, o que siempre se use la misma impresora.
Pero si te fijas lo que hace esa solucion es buscar un punto de
contencion que elimine la concurrencia de la asignacion. Cuando solo
una impresora puede sacar facturas, significa que en un momento dado
solo una factura puede estarse imprimiendo, y por lo tanto es ahi donde
debe generarse el numero de folio. Igual cosa con la persona que genera
la factura.

Ahora, en una base de datos un generador secuencial es un objeto
eminentemente concurrente -- ese es _el proposito_ para el que fue
inventado. No importa que hayan hoyos en la generacion; si hay un
rollback, la secuencia no retrocede. Si tu usas el mecanismo de tomar
el "current value" desde la secuencia sin incrementarla, y sin
bloquearla, otro proceso concurrente puede tomar el mismo valor en el
mismo momento y estaria generando una factura que colisionaria con la
tuya. Como corriges esta distorsion? Una idea podria ser fijarte al
final del proceso, cuando ya sabes que la transaccion no va a abortar,
si es que el "nextval" de la secuencia (y en este punto la incrementas)
corresponde al valor que habias tomado al principio. Y corriges todo el
proceso anterior usando el nuevo valor. Pero en este punto ya la cosa
se puso mas complicada de lo que se pretendia.

Se me ocurren otras ideas para corregir la distorsion, pero no vale la
pena comentarlo porque la verdad es que la otra solucion (SELECT FOR
UPDATE) es mucho mas simple de entender, implementar y usar.

> Cuentame como crees tu que el registro civil otorga los RUN a los recién
> nacidos, o mejor aún, como lo hace para las patentes de los vehículos?

El registro civil es un caso especial, porque la generacion de RUN (rol
unico nacional) no es un proceso centralizado, sino distribuido:
entiendo que cada oficina puede generar independiente de las otras
(ignoro si sera asi todavia). Idem con las patentes de vehiculos. Con
los RUN pasa algo interesante: hay casos de valores repetidos! Por
algun motivo los consulados, que entregan RUN a extranjeros, a veces se
equivocan y dan dos veces el mismo valor a una persona. Y esto suele
ser un problema muy serio para esas dos personas.

En un proceso distribuido, la idea de separar el dominio de generacion
en particiones (i.e. cada oficina tiene un rango asignado) tiene mucho
sentido. En un proceso centralizado, tiene poco o ninguno.

Cuando las facturas estan siendo generadas en una base de datos, es
evidente que ahi mismo hay una centralizacion que seria una tontera no
aprovechar. Si las personas que generan facturas estan repartidas por
toda America Latina o bien todos en la misma oficina con una sola
impresora, da lo mismo -- la base de datos es una sola y se puede
controlar la concurrencia ahi.

--
Alvaro Herrera http://www.CommandPrompt.com/
PostgreSQL Replication, Consulting, Custom Development, 24x7 support

In response to

Browse pgsql-es-ayuda by date

  From Date Subject
Next Message Alvaro Herrera 2006-02-24 03:05:25 Re: que hay de PITR ... ?
Previous Message Raul Caso 2006-02-24 00:47:39 pregunta importacion con copy