ORDA – Manejar una lógica basada en eventos durante las operaciones de base de datos

Traducido automáticamente de Deepl

Esta función sigue adelante con un nuevo paradigma: manejar los datos de una forma basada en eventos. 4D 21 proporciona una serie completa de eventos relacionados con operaciones de base de datos(guardar o soltar).

Los eventos ORDA pueden reemplazar a los triggers y ofrecen muchas más ventajas: más control, permitiéndole codificar su lógica de negocio (incluyendo trabajos que consumen mucho tiempo como imprimir facturas o almacenar datos externos) directamente en una función de clase de datos ORDA. Responden a eventos a nivel de datos como nuevo, modificar, guardar, soltar (CRUD)

Los eventos ORDA ofrecen una granularidad precisa y un sofisticado manejo de errores, lo que conduce a una fuerte integridad de los datos y una mejor organización del código.

Descubra cómo implementar la lógica de negocio apropiada en cada paso de una acción de guardar o soltar.

HDI_ORDA_Events_Guardar_Soltar

Eventos ORDA – Un vals en varios tiempos

En este blogpost anterior, desvelamos el primer evento de una larga serie: el evento tocado.

Los nuevos eventos de operación de base de datos están diseñados para ser utilizados en la capa ORDA a través de entidades manejadas con la palabra clave This lo que no es posible con los triggers.

En comparación con los triggers, estos eventos ofrecen una granularidad más fina para detectar pasos específicos de operaciones de base de datos y un sofisticado tratamiento de errores que puede detener la acción si es necesario.

A diferencia de los triggers, los eventos no sólo permiten ejecutar acciones antes de las acciones de guardar/soltar. También pueden ejecutar acciones durante y después de las operaciones de guardar/soltar.

El manejo de errores es potente, puedes devolver errores personalizados con diferentes severidades e información extra detallada para el usuario final.

Anteriormente, se podían implementar algunas funciones para esto, pero había que llamarlas manualmente siempre que fuera necesario.

Ahora, esta función ofrece una lógica completa basada en eventos, que se activa automáticamente en el momento adecuado. Impleméntelo una vez y deje que el motor 4D lo gestione en tiempo de ejecución:

  • Los datos inconsistentes pueden ser rechazados de antemano sin involucrar la capa de persistencia.
  • Las interacciones con los sistemas externos pueden producirse precisamente cuando los datos 4D son almacenados.
  • Las acciones pueden ser desencadenadas cuando el guardado/eliminación falla

Y buenas noticias, al contrario que los triggers, ORDA no bloquea toda la tabla subyacente de una clase de datos mientras se guarda / suelta una entidad. Varios eventos pueden ejecutarse en paralelo siempre y cuando involucren entidades distintas (esdecir, registros).

Si se depende de un bloqueo completo de toda la tabla para manejar números de secuencia únicos o similares, hay que manejarlo por cuenta propia, por ejemplo con singletons – y esto permite bloquear sólo cuando sea necesario – y tener un control total sobre este proceso.

Las distintas fases de una operación de base de datos

Cuando se ejecuta una acción de guardar o soltar, estos eventos te permiten implementar la lógica de negocio en tres fases distintas de la acción:

  • Validación de la acción de guardar o soltar: Útil para comprobar la coherencia de los datos relativos a esta acción, por ejemplo:
    • ¿El estado de la entidad que se va a eliminar es «A eliminar»?
    • ¿La fecha de salida es < fecha de llegada en una entidad de reserva?

Gracias a este evento, puede detener la acción de guardar/eliminar y devolver un error al usuario final. Esto asegura que los datos serán consistentes y estarán listos antes de entrar en la acción de guardar / soltar.

  • Durante la acción de guardar / soltar: Utilícelo si necesita sincronizar las operaciones de su base de datos con un sistema externo, p . ej:
    • Al guardar una entidad, escribir datos en un disco, crear un documento en un Google Drive, etc.

En este evento, puede devolver errores en caso de que no se detenga la acción. Estos errores pueden ser manejados en el evento posterior descrito a continuación.

  • Después de la acción de guardar o soltar: Aquí puede tomar medidas en relación con los posibles errores surgidos durante las acciones de guardar o soltar, por ejemplo:
    • Marcar un producto como «A comprobar» porque se ha producido un error durante la acción de soltar.

Gracias a estos eventos, cada paso de la acción de guardar o soltar puede tener su propia lógica de negocio dedicada.

Estos eventos se activan tan pronto como la operación de base de datos se activa utilizando ORDA o el servidor REST.

veamos esto en acción con ejemplos

donde implementar los eventos

Los eventos ORDA deben ser implementados en la clase Entity usando la palabra clave event palabra clave.

los eventos validate

Estos eventos se activan antes de la acción de guardar o soltar y pueden detener la acción devolviendo un error. En este caso, los otros eventos descritos a continuación (excepto el evento after) no son disparados.

Se pueden implementar:

  • A nivel de atributo: para comprobar la coherencia de un atributo específico.
  • A nivel de entidad: para comprobar globalmente el contenido de la entidad o comparar atributos

Ejemplo:

En este ejemplo, en la clase ProductsEntity, se ha implementado un eventovalidateSave para el atributomargin . El usuario no puede guardar un producto con un margen inferior al 50%. En este caso, se devuelve un error para detener la acción de guardar y dar información al usuario final.

// ProductsEntity class
//
// validateSave event at attribute level
Function event validateSave margin($event : Object) : Object
	
var $result : Object
	
//The user can't create a product whose margin is < 50%
If (This.margin<50)
	$result:={errCode: 1; message: "The validation of this product failed"; \
	extraDescription: {info: "The margin of this product ("+String(This.margin)+") is lower than 50%"}; seriousError: False}
End if 
return $result

La misma lógica se aplica para un eventovalidateDrop. Por ejemplo, puede impedir que un usuario suelte un producto cuyo estado no sea «A eliminar».

los eventos guardar / soltar

Estos eventos se activan precisamente durante la acción de guardar o soltar y pueden devolver errores si algo va mal. Pueden implementarse

  • A nivel de atributo: para controlar los cambios en los valores de atributos específicos.
  • A nivel de entidad: para comprobar el contenido de la entidad globalmente o comparar atributos

Ejemplo:

En este ejemplo, en la clase ProductsEntity, se ha implementado un evento deguardado para el atributouserManualPath . Cuando se guarda un producto, el documento del manual de usuario se crea en el disco y su ruta se almacena en el atributo userManualPath atributo. Estas dos acciones deben ser coherentes.

Si se produce un error al crear el documento del manual del usuario en el disco, se devuelve un error para dar información y proceder en el siguiente evento (afterSave) que se detalla a continuación.

Tenga en cuenta que el contenido del fichero se genera previamente fuera del evento de guardar porque puede llevar mucho tiempo.

// ProductsEntity class
// saving event at attribute level
Function event saving userManualPath($event : Object) : Object
	
var $result : Object
var $userManualFile : 4D.File
var $fileCreated : Boolean
	
If (This.userManualPath#"")
	$userManualFile:=File(This.userManualPath)
				
	// The user manual document file is created on the disk
	// This may fail if no more space is available
	Try
            // The content of the file has been generated and stored in a map in Storage.docMap previously
	    $docInfo:=Storage.docMap.query("name = :1"; This.name).first()
            $userManualFile.setContent($docInfo.content)
	Catch
		// E.g.: No more space on disk
		$result:={errCode: 1; message: "Error during the save action for this product"; extraDescription: {info: "There is no available space on disk to store the user manual"}}
	End try
End if 
	
return $result

La misma lógica se aplica para un eventodropping. Por ejemplo, puede soltar el documento del manual de usuario mientras suelta el producto.

los eventos after

Estos eventos se activan después de la acción Guardar o Soltar. Dado que la acción ha finalizado, no pueden devolver errores. Su propósito principal es activar la lógica de negocio si se produce un error durante los eventos anteriores.

Si no se produjo ningún error, también pueden manejar la lógica posterior al éxito – por ejemplo, el envío de un correo electrónico de confirmación.

Estos eventos se implementan únicamente a nivel de entidad.

Ejemplo:

En este ejemplo, en la clase ProductsEntity, se ha implementado un eventoafterSave. Si el atributo userManualPath no se ha guardado correctamente con anterioridad, su valor se restablece para que sea coherente con el documento del manual de usuario que falta en el disco.

// ProductsEntity class
Function event afterSave($event : Object)
	
	If (($event.status.success=False) && ($event.status.errors=Null))  // $event.status.errors is filled if the error comes from the validateSave event
		
		// The userManualPath attribute has not been properly saved
		// Its value is reset
		If ($event.savedAttributes.indexOf("userManualPath")=-1)
			This.userManualPath:=""
			This.status:="KO"
		End if 
		
	End if 

La misma lógica se aplica para un eventoafterDroppor ejemplo, cuando al soltar un producto falla, se puede registrar el incidente.

Tenga en cuenta que las operaciones largas deben evitarse en la medida de lo posible en los eventos. Si es posible, dichas operaciones deben implementarse en otro lugar.

No espere a implementar eventos para confiar en una integridad de datos sólida.

👉 Descarga el IDH para sumergirte en los detalles de implementación de los eventos ORDA y mira el vídeo a continuación para tener más detalles sobre la ejecución del IDH.

Añadir el enlace de vídeo ES

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.