Record Locking

4D - Documentation   Français   English   German   Español   4D v11 SQL, Comandos por temas   4D v11 SQL, Lista alfabética de comandos   4D v11 SQL, Constantes por temas   Regresar   Anterior   Siguiente

versión 11 (Modificado)


4D y 4D Server administran automáticamente las bases evitando conflictos entre procesos o entre usuarios. Dos usuarios o dos procesos no pueden modificar el mismo registro u objeto al mismo tiempo. Sin embargo, el segundo usuario o proceso puede acceder simultáneamente al registro 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:

 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.

Bloqueo de registros


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 ha cargado el registro para efectuar una modificación. 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.

Modo sólo lectura y lectura/escritura


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.

Estado sólo lectura

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.

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

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.

Estado lectura/escritura

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.

Cambiar el estado de una tabla

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.

Cargar, modificar y descargar registros


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 registro como bloqueado o desbloqueado. 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, todo registro cargado de esta tabla está bloqueado. Un registro bloqueado no puede guardarse o borrarse desde otro proceso. El modo sólo lectura es el modo recomendado porque autoriza a los otros usuarios a cargar, modificar y luego guardar el registro.

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 ser modificado, 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 LOAD RECORD 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 ser liberado (y por lo tanto desbloqueado para los otros usuarios) con UNLOAD RECORD. Si no se libera un registro, permanecerá bloqueado para los otros usuarios hasta que un nuevo registro actual sea seleccionado. Cambiar el registro actual de una tabla desbloquea automáticamente el registro actual anterior. Debe llamar explícitamente a 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 ATTRIBUTES para ver que usuario y/o proceso tiene bloqueado un registro.

Bucles para cargar registros no bloqueados


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

   READ WRITE ([Clientes])   ` Coloca la tabla en modo lectura/escritura
   Repeat   ` Hace un bucle hasta que el registro esté desbloqueado
      LOAD RECORD ([Clientes])   ` Carga y bloquea el registro
   Until (Not (Locked([Clientes])))
      ` Hacer algo para el registro acá
   READ ONLY ([Clientes])   ` Coloca 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 bloquearlo
   Until (Not (Locked([Inventario])))
   [Inventory]Part Qty := [Inventario]Part Qty - 1   ` Modificar el registro
   SAVE RECORD ([Inventario])   ` Guardar el registro
   UNLOAD RECORD ([Inventario])   ` Permitir que los 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 ATTRIBUTES([Comandos];$Procesos;$Usuario;$Equipo;$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)

Uso de comandos en entornos Multi-usuario o Multi-proceso


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 ATTRIBUTES, Métodos, READ ONLY, Read only state, READ WRITE, UNLOAD RECORD, Variables.


4D - Documentation   Français   English   German   Español   4D v11 SQL, Comandos por temas   4D v11 SQL, Lista alfabética de comandos   4D v11 SQL, Constantes por temas   Regresar   Anterior   Siguiente