Trabajar con el bloqueo optimista de ORDA

Traducido automáticamente de Deepl

4D v17 introduce ORDAORDA, una gran evolución en 4D que está abriendo un mundo de nuevas posibilidades para los desarrolladores de 4D. Una de las ventajas de utilizar ORDA está relacionada con el bloqueo de registros, ya que ORDA ofrece la posibilidad de elegir entre el bloqueo optimista y el pesimista. Después de haber introducido los mecanismos de bloqueo de ORDA, continuamos la serie deORDA para que puedas descubrir cómo trabajar eficientemente con el bloqueo optimista con ORDA.

Ejemplo: bloqueo optimista con ORDA

El bloqueo optimista en pocas palabras

En el modo de bloqueo optimista, los registros no se bloquean explícitamente antes de ser actualizados.

El bloqueo optimista se basa en el sello de los registros. Cada registro tiene un sello interno que se incrementa automáticamente cada vez que se guarda un registro en la base de datos. Si un registro ha sido actualizado desde que se cargó una entidad, los métodos save(), drop() y lock() devolverán un código de estado específico indicando que el sello ha cambiado.

REGISTROS Y ENTIDADES

Como recordatorio, un registro es el registro físico en la base de datos al que se accede a través de una entidad. Una entidad es una referencia a un registro (véase la sección Entidad en el glosario). Los registros se bloquean y desbloquean a través de las entidades.

Ejemplo de código

En el siguiente ejemplo, manejamos dos escenarios en los que el save() falla el método.

C_OBJECT($status;$employee)

// Get the first employee whose last name is "Smith"
$employee :=ds.Employee.query("lastName=:1"; "Smith").first()
If ($employee#Null)
$employee .lastName:="Wates" // Update employee's last name
$status :=$employee.save() // Save employee
if (Not($status.success)) // The save action fails
Case of
// The record has been updated in database since the entity was loaded
: ($status.status=dk status stamp has changed)
alert ("Alguien ha actualizado el registro desde que lo has cargado")
//The record is locked by another process
: ($status.status=dk status locked)
alert ("Alguien ha bloqueado el registro")
End case
end if
end if

CASO 1: LA ENTIDAD HA CAMBIADO

Si el registro se ha actualizado en la base de datos desde que cargó la entidad, el objeto $status devuelto será el siguiente:

{
 "status": 2,
 "statusText": "Stamp has changed",
 "success": false
}

CASO 2: LA ENTIDAD ya está bloqueada

Si el registro en la base de datos ya está bloqueado por otro proceso, el objeto $status devuelto será el siguiente:

{	 	 
 "status": 3,	 	 
 "statusText": "Already Locked",	 	 
 "lockKind": 1,	 	 
 "lockKindText": "Locked By Record",	 	 
 "lockInfo": {	 	 
     "task_id": 5,	 	 
     "user_name": "Mary Smith",	 	 
     "user4d_id": 1,	 	 
     "host_name": "iMac27-Program6",	 	 
     "task_name": "P_10",	 	 
     "client_version": -1610541312	 	 
 },	 	 
 "success": false	 	 
}

Casos comunes

Para acompañar al save() método, ORDA proporciona una opción muy útil: dk auto merge.

dk auto merge intenta fusionar automáticamente las actualizaciones realizadas en una entidad cargada en memoria con las realizadas en el registro de la base de datos. Sin embargo, puede fallar si se actualizan en la entidad cargada las mismas propiedades que otro usuario actualizó en el registro de la base de datos.

Por lo tanto, ofrecemos dos opciones para gestionar esto.

1- ANULAR LAS ACTUALIZACIONES REALIZADAS EN LA BASE DE DATOS

En el ejemplo siguiente, el método save() con dk auto merge falla.

Tenemos la certeza de que queremos anular las actualizaciones realizadas en la base de datos por otro proceso.

Este caso lo gestionamos de la siguiente manera:

1- Antes de guardar, utilizamos el método clone(). Esto crea una nueva referencia en nuestra entidad actualizada. Es útil para hacer una copia de una entidad para reutilizarla más tarde.

Cuando el método save() método falla, nosotros

2- Usamos el método reload() para recargar nuestra entidad desde el registro de la base de datos y así obtener un sello actualizado.

3- Usando la entidad clonada, volvemos a aplicar nuestras actualizaciones.

4- Guardamos de nuevo la entidad y comprobamos el estado devuelto.

C_OBJECT($status;$employee;$clonedEmployee)
// Get the first employee whose last name is "Smith"
$employee :=ds.Employee.query("lastName=:1"; "Smith@").first()

If ($employee#Null)
// Update the last name
$employee .lastName:="Dunaway"
// Clone the loaded entity
$clonedEmployee :=$employee.clone()
// Save the entity with auto merge option
$status :=$employee.save(dk auto merge)
// The save action fails
While (Not($status.success))
// The auto merge failed
If ($status.status=dk status automerge failed)
// Reload the entity. The stamp will be updated
$employee .reload()
// Reapply the update on last name
$employee .lastName:=$clonedEmployee.lastName
// Save the entity
$status :=$employee.save(dk auto merge)
End if
End while
End if

2- CONSTRUYA UNA INTERFAZ DE USUARIO PARA GESTIONAR MANUALMENTE LOS CONFLICTOS ENTRE LAS ENTIDADES Y LOS REGISTROS

ORDA proporciona métodos útiles para ayudarte a construir una interfaz que permita a los usuarios elegir entre sus actualizaciones y otras realizadas al mismo tiempo.

A continuación, un resumen rápido de estos métodos. Consulte la documentación para obtener más detalles.

  • touchedAttributes() método: devuelve los atributos a los que se ha accedido desde que se cargó o guardó una entidad.
  • diff() método: compara dos entidades

En el IDH proporcionado, verá cómo construir una interfaz de este tipo.

Avatar
• Propietario de producto - Marie-Sophie Landrieu-Yvert ingresó al equipo de 4D Product como Propietario de producto en 2017. Como tal, está a cargo de escribir las historias de los usuarios y luego traducirlas en especificaciones funcionales. Su papel es también asegurarse de que la implementación de la funcionalidad entregada cumpla con las necesidades del cliente. Marie-Sophie se graduó en la Escuela de Ingeniería de ESIGELEC y comenzó su carrera como ingeniera en IBM en 1995. Participó en varios proyectos (de mantenimiento y creación) y trabajó como desarrolladora de Cobol. Luego trabajó como diseñadora de UML y desarrolladora de Java. Sus principales funciones fueron analizar y redactar requisitos funcionales, coordinar los equipos de negocio y de desarrollo.