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. > > > > > >