Re: Bloqueo en registro-tabla

From: "Mariano Reingart" <mariano(at)nsis(dot)com(dot)ar>
To: "suso" <jlcubas(at)terra(dot)es>
Cc: <pgsql-es-ayuda(at)postgresql(dot)org>
Subject: Re: Bloqueo en registro-tabla
Date: 2009-06-15 23:05:47
Message-ID: DF5889E6CFD7463095DE37639B73C1DD@pc1
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-es-ayuda

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

In response to

Responses

Browse pgsql-es-ayuda by date

  From Date Subject
Next Message jsgarcia 2009-06-15 23:47:44 Borrar registro con FK
Previous Message suso 2009-06-15 21:59:11 Re: Bloqueo en registro-tabla