Re: Duda con cursor + SELECT FOR UPDATE

From: Arcel Labrada Batista <alabradab1982(at)gmail(dot)com>
To: Jorge Sanchez <espartano(dot)mail(at)gmail(dot)com>
Cc: Lista PostgreSQL <pgsql-es-ayuda(at)postgresql(dot)org>
Subject: Re: Duda con cursor + SELECT FOR UPDATE
Date: 2019-05-21 20:20:03
Message-ID: CAJ52oeP3NUD+TjY1hxdousWHTdoYbx6z+3iQLZO_7Ywc0_=Zsg@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-es-ayuda

por que no piensas en una función trigger.
antes de insertar un registro en OUT, verificar que tengas existencia en
IN, decrementas cantidades de ser posible y dejas insertar en OUT, de lo
contrario no permitir inserción.

El mar., 21 may. 2019 a las 13:20, Jorge Sanchez (<espartano(dot)mail(at)gmail(dot)com>)
escribió:

> On Tue, May 21, 2019 at 7:13 AM Stephen Amell <mrstephenamell(at)gmail(dot)com>
> wrote:
> >
> > Hola,
> >
> > La funcion es transaccional en si, o sea, que fuera de tu scope no se va
> > a ver el bloqueo de registros. Lo tenes que hacer por afuera antes de
> > llamar a la funcion, commitear y recien ahi empezar a laburar.
>
> Difiero, al aplicar el SELECT FOR UPDATE dentro del Store procedure he
> visto que los registros se bloquean para cualquier transacción no
> solamente para la transacción que va dentro de la función, y es
> precisamente ese comportamiento el que espero.
>
> >
> > for!!!! en una DB!!!!! no se si matarte o abrazarte... ;P
>
> Bueno, recorrer los resultados de un select 1 a 1 en un FOR es
> admisible de hecho la base de datos provee los mecanismos necesarios
> para esto:
>
> https://www.postgresql.org/docs/9.4/plpgsql-control-structures.html
>
> >
> > trata de pasar todo a joins que te va a mejorar la vida.
> >
>
> Precisamente estoy eliminando un join que me da problemas por que el
> bloqueo de registros con SELECT FOR UPDATE no funciona si tienes
> agrupaciones, entonces para mi caso es preferible hacer un select en
> la tabla donde voy a actualizar en vez de hacer un join que me da casi
> todo el resultado en un paso y luego sobre ese resultado actualizar
> los registros que necesito, como esta función la hicieron de esa forma
> (con un join y sin los bloqueos necesarios) cuando la base de datos
> tiene mucha concurrencia y se lanza el store procedure de forma casi
> simultánea (la concurrencia en este caso podría ser valida) los
> registros se actualizan de forma concurrente pero los datos pierden
> integridad por la forma en que están estructurados (es una base de
> datos legada y en producción).
>
> Básicamente el problema que estoy tratando es un problema de entradas
> y salidas, voy a tratar de explicarme un poco mejor:
>
> Tengo una tabla IN donde existe un registro por cada entrada de
> productos por ejemplo que están asociados a una cuenta, es decir cada
> registro en IN pertenece a una cuenta y tiene el numero de productos
> que entraron y puede haber multiples registros de entrada, tengo otra
> tabla OUT que registra salidas, multiples salidas pueden estar
> asociadas a una sola entrada, si hago un join entre estas dos tablas
> para sumarisar las salidas que corresponden a una entrada (SUM() +
> GROUP BY) no puedo ejecutar SELECT FOR UPDATE en IN para bloquear los
> registros de entrada, entonces quité el join y ejecuto un SELECT FOR
> UPDATE en IN (obviamente con el respectivo WHERE para seleccionar
> todos los registros IN asociados a una cuenta y demás restricciones) y
> por cada registro verifico las correspondientes salidas en OUT para
> verificar si el registro en IN aún tiene productos remanentes y
> cuantos y en base a eso agregar registros en OUT y actualizar el
> registro en IN para marcarlo como "agotado", si no realizo el bloqueo
> de registros que posiblemente serán actualizados en cada llamada al
> store procedure y se ejecuta nuevamente el store procedure la
> contabilidad podría verse comprometida, aplicando SELECT FOR UPDATE
> entiendo que si se ejecuta el store procedure nuevamente antes de que
> termine el primero, el segundo quedará bloqueado (puesto que
> posiblemente va a actualizar los mismos registros) hasta que el que
> fue lanzado primero termine.
>
> Espero haberme explicado mejor.
>
> > salu2
>
> Saludos.
>
>
> > On 2019-05-20 20:42, Jorge Sanchez wrote:
> > > Buenas tardes lista, tengo la siguiente duda y espero me puedan ayudar
> > > a resolverla:
> > >
> > > Tengo en una función de pl/pgsql un ciclo FOR que itera sobre el
> > > resultado de un SELECT con la particularidad de que dicho SELECT tiene
> > > la cláusula FOR UPDATE ya que quiero bloquear los registros de dicho
> > > SELECT puesto que van a ser actualizados, por algún lugar leí que los
> > > ciclos FOR crean implícitamente un cursor para iterar sobre los
> > > resultados, mi duda en concreto es si los registros que regresa el
> > > SELECT al FOR se marcan como bloqueados al inicio del FOR o se
> > > bloquean van siendo cargados en el cursor?
> > >
> > > Gracias de antemano.
> > >
> > >
> > >
>
>
>

In response to

Browse pgsql-es-ayuda by date

  From Date Subject
Next Message Fernando A 2019-05-24 23:59:57 Como inhabilitar el acceso a postgres cambiando MD5 a Trust en PG
Previous Message Jorge Sanchez 2019-05-21 17:19:59 Re: Duda con cursor + SELECT FOR UPDATE