Re: Bloqueo en registro-tabla

From: suso <jlcubas(at)terra(dot)es>
To: Mariano Reingart <mariano(at)nsis(dot)com(dot)ar>
Cc: pgsql-es-ayuda(at)postgresql(dot)org
Subject: Re: Bloqueo en registro-tabla
Date: 2009-06-16 00:08:00
Message-ID: 4A36E260.6020604@terra.es
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-es-ayuda

Eso es justamente lo que necesitaba, un bloqueo pero por tiempo, no me
hace falta tanto tiempo, en este caso concreto, según me han comentado,
con 90' está sobrado, por supuesto, que en cuanto el médico grabe los
datos o salga de la aplicación, ésta mira si hay bloqueo en el último
registro usado, y en caso afirmativo, desbloquea y sale, el único
problema que yo tenía, era que si el médico apagaba el pc sin salir del
programa, o se iba la luz, o cosas así, el registro-tabla según el caso,
se quedaría bloqueada, de la forma que me has comentado, está resuelto,
ya que según veo, aunque no se autodesbloquea, si lo hace cuando un
segundo usuario pasado "x" tiempo intenta acceder, si hubiera estado
bloqueado, se desbloquea en ese momento y se queda libe.
Muchas gracias
UN saludo
Suso
> "suso" <jlcubas(at)terra(dot)es>:
>> Hola Mariano, como comenté en el mail despues de éste, xmin esta en cada
>> tabla, lo que me hace suponer que es un campo "genérico" o algo así,
>> por lo que me coemntas entonces es eso, cambia de valor en función de
>> si algún campo(el que sea) ha cambiado de valor.
>
> Si, xmin podes usarlo para detectar si la fila se modificó, no para
> bloquearla.
>
>> Esto lo que me hace(siempre y cuando lo que digo sea correcto) es
>> decirme si ha cambiado o no, peor no impide que alguien lo cambie, que
>> es mi objetivo(y el de los medicos, según me han comentado), impedir
>> que alguien, o sea, mas de uno, pueda acceder a los datos, o la menos
>> cambiarlos, mientras ellos están trabajando, quizás no se muy correcto
>> esta manera de plantear el tema, es decir, el bloqueo.
>
> No, pero usando xmin y un bloqueo físico más corto podes garantizar no
> "pisar" los datos (sobreescribir lo que haya cambiado otra persona).
>
> Al empezar, haces:
> SELECT *, xmin FROM historia_clinica WHERE numero=1234;
> -- guardas el xmin y empieza la edición (por ej, en variable xmin0)
>
> -- al guardar, comienzo una transacción
> BEGIN;
> -- selecciono el xmin actual y bloqueo la tabla para que otro no pueda
> modificar ese registro
> SELECT xmin FROM historia_clinica WHERE numero=1234 FOR UPDATE;
> -- si xmin != xmin0 lanzar un error porque los datos se modificaron
> (ROLLBACK)
> -- si xmin == xmin0, hacer el UPDATE y COMMIT
>
>> El tema es que no se como hacerlo, si no es poniendo un flag en una
>> tabla en concreto, y com me recomendó Alvaro, que caduque(que no se
>> cómo puedo pasarle el tiempo de caducidad) a no ser que mediante algun
>> procedimiento almacenado, trigger o no sé.
>
> Hacer un bloqueo lógico en cada registro que caduque (por ej. 24hs hs)
> podes hacerlo relativamente facil (con un campo fecha_bloqueo donde
> insertas el valor de now()):
> BEGIN;
> SELECT fecha_bloqueo+CAST('24 hours' AS INTERVAL)<now() AS bloqueado
> FROM historia_clinica WHERE numero=1234 FOR UPDATE;
> -- si bloqueado es TRUE, todavia no paso el periodo de 24hs), hacer
> ROLLBACK e informar al usuario que el registro esta bloqueado.
> -- si bloqueado es NULL o falso (por ej., pasaron 24hs), pones una nueva
> fecha de bloqueo (que comienza ahora):
> UPDATE historia_clinica SET fecha_bloqueo=now() WHERE numero=1234;
> COMMIT;
>
> Obviamente cuando el usuario modifica definitivamente el registro, tenes
> que establecer la fecha de bloqueo a NULL para liberar el registro, y
> comparar con xmin que igualmente no se haya modificado el registro, como
> en el primer ejemplo (recordando que si pasaron 24hs el registro pudo
> igualmente modificarse, ya que el bloqueo es lógico y no físico)
>
> Se podría ir más lejos con triggers para evitar que otro usuario no
> pueda escribir en el mismo registro (haciendo un bloqueo "más físico" y
> no tan lógico), pero esto ya sería mucho más complejo.
>
> Espero que te sirva,
> Sds
> Mariano
>
>> Me imagino que con trabajo y algo de imaginación:)
>> Un saludo
>> Suso
>>> suso wrote:
>>>> Acabo de ver "xmin", veo que es un "campo" para cada tabla, es
>>>> correcto? Si es así, me supongo, no nos dice el valor anterior de
>>>> cada campo, sólo si en la tabla ha habido algún cambio, es asi?
>>>
>>> Si, si no me equivóco, xmin es un campo del sistema para todas las
>>> tablas.
>>>
>>> Informa el valor actual, o sea, si en un momento haces:
>>>
>>> SELECT *, xmin FROM tabla WHERE ...;
>>>
>>> xmin te va a dar un número tipo 1290349 para un registro puntual
>>>
>>> Luego, si ese registro cambia, xmin te va a dar otro número, pero
>>> para la próxima consulta (tenés que hacer un nuevo SELECT)
>>>
>>> O sea, antes de hacer un UPDATE haces un nuevo SELECT, si te da otro
>>> xmin es porque los datos se modificaron (te conviene hacerlo en la
>>> misma transacción el SELECT y el UPDATE para evitar inconsistencias)
>>>
>>> Sds
>>> Mariano
>>>
>>>
>>>> Un saludo
>>>> Suso
>>>>> Hola Mariano, pero no sé como poder obtener esos valores(xmin), es
>>>>> decir, es un simple recordset apuntando a , dónde?
>>>>> Ese valor es uno sólo para todos los campos de cada tabla?
>>>>> Gracias
>>>>> Un saludo
>>>>> Suso
>>>>>
>>>>>> suso wrote:
>>>>>>> Ahora mismo lo tengo "casi" como dices, es decir, tengo un campo,
>>>>>>> en una sola tabla, que es "la referencia/consulta" en cada
>>>>>>> insercion-update Lo de la fecha me parece muyyy buena idea.
>>>>>>>
>>>>>>> Aunque, por vuestros comentarios, es mejor que la descarte, y
>>>>>>> pruebe a comparar los datos "iniciales" preguardados, con los que
>>>>>>> se van a guadar, y así saber si alguien ha intentado algo, y si es
>>>>>>> así, darle al médico la opción de actualizar.
>>>>>>
>>>>>> No hace falta comparar todos los datos, podes usar la columna de
>>>>>> sistema xmin, que te da la identidad (id de transacción) de la
>>>>>> versión de la fila.
>>>>>> Si originalmente leiste la fila y luego se modificó, cuando leas
>>>>>> nuevamente antes de grabar el campo xmin va a tener otro valor:
>>>>>> http://www.postgresql.org/docs/current/interactive/ddl-system-columns.html
>>>>>>
>>>>>>
>>>>>>
>>>>>> Sds
>>>>>> Mariano
>>>>>> --
>>>>>> TIP 2: puedes desuscribirte de todas las listas simultáneamente
>>>>>> (envía "unregister TuDirecciónDeCorreo" a
>>>>>> majordomo(at)postgresql(dot)org)
>>>>>
>>>>> --
>>>>> TIP 2: puedes desuscribirte de todas las listas simultáneamente
>>>>> (envía "unregister TuDirecciónDeCorreo" a
>>>>> majordomo(at)postgresql(dot)org)
>>>>
>>>> --
>>>> TIP 3: Si encontraste la respuesta a tu problema, publícala, otros te
>>>> lo agradecerán
>>>
>>> --
>>> TIP 3: Si encontraste la respuesta a tu problema, publícala, otros te
>>> lo agradecerán
>>>
>>
>> --
>> TIP 10: no uses HTML en tu pregunta, seguro que quien responda no
>> podrá leerlo
>>
>
> --
> TIP 4: No hagas 'kill -9' a postmaster
>

In response to

Browse pgsql-es-ayuda by date

  From Date Subject
Next Message Alejandro D. Burne 2009-06-16 01:15:12 Re: AYUDA CON JOBS
Previous Message jsgarcia 2009-06-15 23:47:44 Borrar registro con FK