4D v16.3

Record Locking

Inicio

 
4D v16.3
Record Locking

Record Locking  


 

 

4D y 4D Server administran automáticamente las bases evitando conflictos entre procesos o entre usuarios. Dos usuarios o dos procesos no pueden modificar al mismo tiempo el mismo registro u el mismo objeto. El segundo usuario o proceso puede acceder simultáneamente al registro u objeto en modo sólo lectura.

Hay muchas razones para utilizar los comandos multiusuario:

  •  Modificación de registros por programación.
  •  Utilización de una interfaz de usuario personalizada para operaciones multiusuario.
  •  Almacenamiento de modificaciones relacionadas con una transacción.

Hay tres conceptos importantes a tener en cuenta cuando se utilizan comandos en una base multiproceso:

  • En un proceso, cada tabla está en modo sólo lectura o lectura/escritura.
  • Los registros se bloquean cuando son cargados y se desbloquean cuando son descargados.
  • Un registro bloqueado no puede ser modificado.

En las siguientes secciones como convención, la persona que efectúa una operación en la base multiusuarios es el usuario local. Las otras personas que utilizan la base son los otros usuarios. La discusión es desde el punto de vista del usuario local. De la misma forma, desde el punto de vista multiproceso, el proceso que se ejecuta una operación en la base es el proceso actual. Todo otro proceso en curso de ejecución está diseñado como otro proceso. La discusión es desde el punto de vista del proceso actual.

Un registro bloqueado no puede ser modificado por el usuario local o el proceso actual. Un registro bloqueado puede ser cargado, pero no modificado. Un registro se bloquea cuando uno de los otros usuarios o procesos carga el registro para efectuar una modificación o cuando el registro está apilado. Sólo el usuario que modifica el registro ve el registro como desbloqueado. Todos los otros usuarios y procesos ven el registro como bloqueado y por lo tanto no disponible para modificación. Una tabla debe estar en modo lectura/escritura para que un registro se cargue como desbloqueado.

Cada tabla de una base está en modo lectura/escritura o en modo sólo lectura para cada usuario y proceso de la base. Sólo lectura significa que los registros de la tabla pueden ser cargados pero no modificados. Lectura/escritura significa que los registros de la tabla pueden ser cargados y modificados si ningún otro usuario/proceso ha bloqueado el registro previamente.

Note que si cambia el estado de una tabla, el cambio toma efecto para el siguiente registro cargado. Si ya hay un registro cargado cuando cambia el estado de la tabla, el registro no se afecta por el cambio de estado.


Cuando una tabla está en modo sólo lectura y se carga un registro, el registro está siempre bloqueado. En otras palabras, el registro puede mostrarse, imprimirse y utilizarse, pero no modificarse.

Note que el modo sólo lectura aplica únicamente a la edición de registros existentes. El estado sólo lectura no afecta la creación de nuevos registros. Puede añadir registros a una tabla sólo lectura utilizando los comandos CREATE RECORD y ADD RECORD  o los comandos de menús del entorno Diseño (en este caso, los registros, en creación son bloqueados para todos los otros usuarios/procesos). Note que el comando ARRAY TO SELECTION no se ve afectado por el estado sólo lectura ya que permite crear y modificar registros.

4D define automáticamente una tabla en modo sólo lectura para los comandos que no requieren acceder en escritura a los registros. Estos comandos son:  DISPLAY SELECTION, DISTINCT VALUES, EXPORT DIF, EXPORT SYLK, EXPORT TEXT, _o_GRAPH TABLE, PRINT SELECTION, PRINT LABEL, QR REPORT, SELECTION TO ARRAY, SELECTION RANGE TO ARRAY.

Puede saber en cualquier momento el estado de una tabla utilizando la función Read only state.

Antes de ejecutar cualquiera de estos comandos, 4D guarda el estado actual de la tabla (sólo lectura o lectura/escritura) para el proceso actual. Después de ejecutar el comando, el estado inicial se restablece.

Cuando una tabla está en lectura/escritura y se carga un registro, el registro estará desbloqueado si ningún otro usuario ha bloqueado el registro primero. Si el registro está bloqueado por otro usuario, el registro se carga como un registro bloqueado que no puede ser modificado por el usuario local.

Una tabla debe estar en modo lectura/escritura y el registro cargado para que sea desbloqueada y por lo tanto modificable.

Si un usuario carga un registro de una tabla en modo lectura/escritura, ningún otro usuario puede cargar ese registro para modificación. Sin embargo, otros usuarios pueden añadir registros a la tabla, bien sea a través de los comandos CREATE RECORD o ADD RECORD o manualmente en el entorno Diseño.

El modo lectura/escritura es el estado por defecto para todas las tablas cuando una base se abre y se inicia un nuevo proceso.

Puede utilizar los comandos READ ONLY y READ WRITE para cambiar el estado de una tabla. Si quiere cambiar el estado de una tabla para volver un registro de sólo lectura o lectura/escritura, puede ejecutar el comando antes de cargar el registro. Todo registro ya cargado no se ve afectado por los comandos READ ONLY y READ WRITE.

Cada proceso tiene su propio estado (sólo lectura o lectura/escritura) para cada tabla en la base.

Por defecto, si no se utiliza el comando READ ONLY, todas las tablas están en modo lectura/escritura.

Para que el usuario local pueda modificar un registro, la tabla debe estar en modo lectura/escritura y el registro debe cargarse y desbloquearse.

Cada uno de los comandos que carga un registro actual (si hay uno), tales como NEXT RECORD, QUERY, ORDER BY, RELATE ONE, etc., define el estado bloqueado o desbloqueado del registro. El registro se carga en función del estado actual de su tabla (sólo lectura o lectura/escritura) y de su disponibilidad. Un registro también puede cargarse de una tabla relacionada por uno de los comandos que provoca una relación automática.

Si una tabla está en modo lectura únicamente, para un proceso o usuario, todo registro de esta tabla se carga en modo lectura únicamente, lo que significa que no podrá ser modificado o eliminado por el proceso o usuario. Este modo se recomienda para la visualización o recuperación de datos, ya que no impide que otros usuarios o procesos accedan a los registros de esta tabla en modo lectura/escritura si es necesario.

Si una tabla está en modo lectura/escritura, todo registro cargado de esta tabla está desbloqueado sólo si ningún otro usuario ha bloqueado el registro primero. Un registro desbloqueado puede ser modificado y guardado. Una tabla debe ser colocada en modo lectura/escritura antes de que un registro necesite ser cargado, modificado, y luego guardado.

Si el registro debe modificarse, utilice la función Locked para probar si el registro está bloqueado por otro usuario. Si un registro está bloqueado (Locked devuelve True), cargue el registro con el comando [#cmd id="52"/] y pruebe nuevamente si el registro está bloqueado o no. Esta secuencia debe continuar hasta que el registro sea desbloqueado (Locked devuelve False).

Cuando termine las modificaciones a un registro, el registro debe liberarse (y por lo tanto desbloquearse para los otros usuarios) con UNLOAD RECORD. Si no se descarga un registro, permanecerá bloqueado para todos los demás usuarios hasta que se seleccione un registro actual diferente. Cambiar el registro actual de una tabla desbloquea automáticamente el registro actual anterior. Debe llamar explícitamente UNLOAD RECORD si no cambia el registro actual. Este principio aplica a los registros existentes. Cuando se crea un nuevo registro, puede guardarse sin importar el estado de la tabla a la cual pertenece.

Nota: cuando se utiliza en una transacción, el comando UNLOAD RECORD descarga el registro actual sólo para el proceso que administra la transacción. Para los otros procesos, el registro permanece bloqueado hasta que la transacción no sea validada (o cancelada).

Utilice el comando LOCKED BY para ver que usuario y/o proceso tiene un registro bloqueado.

Nota: una buena práctica es colocar todas las tablas en modo de sólo lectura cuando se inicia cada proceso (utilizando la sintaxis READ ONLY(*)) a continuación, se pone cada tabla en modo lectura/escritura sólo cuando sea necesario. El acceso a las tablas en modo de sólo lectura es más rápido y más económico en memoria. Por otra parte, cambiando el estado de una tabla se optimiza en modo cliente/servidor, ya que no causa ningún tráfico de red adicional: la información sólo se envía al servidor cuando se ejecuta un comando que requiere un acceso adecuado a la tabla.


El siguiente ejemplo muestra el bucle más simple para cargar un registro no bloqueado:

 READ WRITE([Customers]` Define el estado de la tabla en lectura/escritura
 Repeat ` Hace un bucle hasta que el registro esté desbloqueado
    LOAD RECORD([Customers]` Carga el registro y lo bloquea
 Until(Not(Locked([Customers])))
  ` Hacer algo para el registro acá
 READ ONLY([Customers]` Define el estado de la tabla en modo sólo lectura

El bucle continúa hasta que el registro sea desbloqueado.

Un bucle como este se utiliza únicamente cuando es poco probable que el registro esté bloqueado por otra persona, ya que el usuario tendría que esperar hasta que el bucle termine. Este bucle no se utiliza a menos que el registro sólo sea modificable por un método.

El siguiente ejemplo utiliza el bucle anterior para cargar un registro desbloqueado y modificar el registro:

 READ WRITE([Inventario])
 Repeat ` Bucle hasta que el registro sea desbloqueado
    LOAD RECORD([Inventario]) ` Cargar el registro y lo define como bloqueado
 Until(Not(Locked([Inventario])))
 [Inventory]Part Qty:=[Inventario]Part Qty-1 ` Modifica el registro
 SAVE RECORD([Inventario]) ` Guarda el registro
 UNLOAD RECORD([Inventario]) ` Permite que otros usuarios lo modifiquen
 READ ONLY([Inventario])

El comando MODIFY RECORD notifica automáticamente al usuario si un registro está bloqueado y evita que el registro sea modificado. El siguiente ejemplo evita esta notificación automática probando el registro primero con la función Locked. Si el registro está bloqueado, el usuario puede cancelar.

Este ejemplo prueba eficientemente si el registro actual está bloqueado para la tabla [Comandos]. Si está bloqueado, el proceso es retrasado por el método por un segundo. Esta técnica puede utilizarse en un desarrollo multiusuario o multiproceso:

 Repeat
    READ ONLY([Comandos]) ` No necesita lectura/ escritura por el momento
    QUERY([Comandos])
  ` Si la búsqueda se terminó y lo registros son devueltos
    If((OK=1) & (Records in selection([Comandos])>0))
       READ WRITE([Comandos]) ` Coloque la tabla en modo lectura/escritura
       LOAD RECORD([Comandos])
       While(Locked([Comandos]) & (OK=1)) `Si el registro está bloqueado,
  ` bucle hasta que el registro sea liberado
  ` ¿Quién bloqueó el registro?
          LOCKED BY([Comandos];$Procesos;$Usuario;$UsuarioSesion;$Nombre)
          If($Proceso=-1) ` ¿El registro ha sido borrado?
             ALERT("El registro ha sido borrado en el intervalo.")
             OK:=0
          Else
             If($Usuario="") ` ¿Está en modo monusuario?
                $Usuario:="usted"
             End if
             CONFIRM("El registro está siendo utilizado por "+$Usuario+" en el proceso "+$Nombre+" Proceso.")
             If(OK=1) ` Si quiere esperar algunos segundos
                DELAY PROCESS(Current process;120) ` Espere algunos segundos
                LOAD RECORD([Comandos]) ` Trate de cargar el registro
             End if
          End if
       End while
       If(OK=1) ` El registro está desbloqueado
          MODIFY RECORD([Comandos]) ` Puede modificar el registro
          UNLOAD RECORD([Comandos])
       End if
       READ ONLY([Comandos]) ` Volver a modo sólo lectura
       OK:=1
    End if
 Until(OK=0)

Ciertos comandos del lenguaje realizan acciones particulares cuando encuentran un registro bloqueado.

Esta es la lista de estos comandos y sus acciones cuando encuentran un registro bloqueado.

  • MODIFY RECORD: muestra una caja de diálogo indicando que el registro está en uso. El registro no se muestra, por lo tanto el usuario no puede modificarlo. En el entorno Diseño, el registro se muestra en estado sólo lectura.
  • MODIFY SELECTION: se comporta normalmente excepto cuando el usuario hace doble clic en un registro para modificarlo. MODIFY SELECTION muestra una caja de diálogo indicando que el registro está en uso y luego permite el acceso al registro en modo sólo lectura.
  • APPLY TO SELECTION: carga un registro bloqueado, pero no lo modifica. APPLY TO SELECTION puede utilizarse para leer información de una tabla sin tener cuidados especiales. Si el comando encuentra un registro bloqueado, el registro se coloca en el conjunto sistema LockedSet.
  • DELETE SELECTION: no borra los registros bloqueados; simplemente los ignora. Si el comando encuentra un registro bloqueado, el registro se pone en el conjunto sistema LockedSet.
  • DELETE RECORD: este comando se ignora si el registro está bloqueado. No se devuelve ningún error. Debe probar que el registro está desbloqueado antes de ejecutar este comando.
  • SAVE RECORD: este comando se ignora si el registro está bloqueado. No se devuelve ningún error. Debe probar que el registro está desbloqueado antes de ejecutar este comando.
  • ARRAY TO SELECTION: no guarda los registros bloqueados. Si el comando encuentra un registro bloqueado, el registro se pone en el conjunto sistema LockedSet.
  • GOTO RECORD: en una base multiusuarios/multiprocesos los registros pueden ser añadidos o borrados por otros usuarios, por lo tanto los números de los registros pueden variar. Sea prudente cuando referencie un registro directamente un registro por número en una base multiusuarios.
  • Conjuntos: sea especialmente cuidadoso con los conjuntos, ya que la información en la que se basa el conjunto puede ser cambiada por otro usuario o proceso.



Ver también 

LOAD RECORD
Locked
LOCKED BY
Métodos
READ ONLY
Read only state
READ WRITE
UNLOAD RECORD
Variables

 
PROPIEDADES 

Producto: 4D
Tema: Registros (bloqueo)

 
HISTORIA 

 
ARTICLE USAGE

Manual de lenguaje 4D ( 4D v16)
Manual de lenguaje 4D ( 4D v16.1)
Manual de lenguaje 4D ( 4D v16.2)
Manual de lenguaje 4D ( 4D v16.3)