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.m...@gmail.com>) escribió: > On Tue, May 21, 2019 at 7:13 AM Stephen Amell <mrstephenam...@gmail.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. > > > > > > > > > > > >