Alvaro Herrera escribió:
Oswaldo Hernández escribió:

1.
Si para 'marcar' un registro en uso utilizo:
  pg_try_advisory_lock(oid_de_tabla, id_registro)

me puedo encontrar en un futuro que el id_registro (bigint) supera
la capacidad del int4.

De momento estoy parcheando la situación, robandole un byte al oid
de la tabla (asumo que el oid de tabla nunca sobrepasará
16.777.215), y asignándoselo al id de registro con la siguiente
formula:
  pg_try_advisory_lock( (oid_de_tabla::int8 << 40) + id_registro )

Pero, ¿hay alguna forma de obtener un id único, tipo bigint, que
identifique un registro de forma global?

No.  Tus suposiciones son peligrosas.  Podrías usar
pg_advisory_lock(int8) pero entonces no tendrías acceso a poner el OID
de la tabla.  Creo que lo más sano sería no usar un id_registro int8;
¿no te alcanza con los cuatro mil millones de identificadores que provee
int4?


La cuestión es que mis id de registro no son normales, simplificando avanzan de 100 en 100, entonces en rango se reduce a 42 millones. Esa es la causa de querer aprovechar ese byte. Lo meditaré a ver que solución tomo.


2.
En algunos momentos utilizo pg_advisory_unlock_all() para asegurarme
que no queda ningún advisory lock pendiente de liberar.

La duda es que si, al igual que postgres genera locks
automaticamente al realizar select, etc. ¿puede postgres utilizar
también advisory_locks y entonces anularlos yo indebidamente al
ejecutar pg_advisory_unlock_all?

No.  Los candados de pg_advisory están en un espacio de locks separado
de los locks de sistema.  Lo que sí puede pasar es que en un año más
agregues otros candados "advisory" que no quieras liberar.  Te
recomendaría no usar unlock_all si puedes evitarlo.


OK. He hecho una función que lee la tabla pg_locks, obtiene los advisory del pid actual y los desbloquea uno a uno, reservando un rango para otros posibles usos.

Gracias Alvaro.

--
Oswaldo Hernández
--
TIP 10: no uses HTML en tu pregunta, seguro que quien responda no podrá leerlo

Responder a