Evitar actualizaciones perdidas

Objective

After completing this lesson, you will be able to utilice Etags para protegerse contra la pérdida de datos

Control de concurrencia

A continuación, queremos obtener un resumen de las opciones que proporciona CAP para garantizar la integridad de los datos cuando las modificaciones simultáneas se ejecutan simultáneamente.

Los tiempos de ejecución de CAP admiten diferentes formas de evitar situaciones de actualización perdida, como se documenta en el siguiente vídeo.

Bloqueo optimista

Comenzamos con el concepto de bloqueo optimista, que se basa en ETags (etiquetas de entidad). Para habilitar ETags para una entidad modelo, añada la anotación @odata.etag a un elemento de la definición de entidad.

En el ejemplo mostrado, el elemento modifiedAt del aspecto gestionado se define como elemento ETag tanto para la entidad Books como para la entidad Authors. Para ello se utiliza la directiva annotate , que permite anotar las definiciones existentes.

Nota

Los elementos cuyo contenido cambia de forma unívoca cada vez que se actualiza un registro de datos son adecuados como elemento ETag. Por lo tanto, el elemento modifiedAt del aspecto gestionado predefinido es un buen candidato. También puede utilizar contadores de actualización o UUID, que se vuelven a calcular en cada actualización.

La idea de un ETag es identificar una versión específica de una entidad, en nuestro ejemplo la versión de un libro o un autor. Esto se puede utilizar para garantizar la integridad de los datos, como se explica en el siguiente ejemplo, sin utilizar bloqueos.

Supongamos que recuperamos un autor específico a través de la siguiente solicitud porque queremos modificar sus datos:

Code Snippet
1
GET Authors(18f76942-bfb3-40c5-8300-f999f14e9cc2)

Con esta solicitud, la versión del autor, es decir, el valor del elemento ETag modifiedAt, se devuelve automáticamente a través de la cabecera de respuesta HTTP ETag , por ejemplo:

Code Snippet
1
ETag: W/"2024-03-15T11:30:48.069Z"

Para reescribir datos modificados en el autor, el valor ETag recibido se utiliza de la siguiente manera en la cabecera HTTP If-Match de la solicitud de modificación correspondiente:

Code Snippet
1234567
PUT Authors(18f76942-bfb3-40c5-8300-f999f14e9cc2) If-Match: W/"2024-03-15T11:30:48.069Z" Content-Type: application/json { ... }

A continuación, CAP verifica si el contenido del elemento modifiedAt ha cambiado entretanto. Si no es así, los datos de autor se modifican en la base de datos y se actualiza el campo modifiedAt ETag. En caso afirmativo, esto significa que el autor se ha modificado mediante otra solicitud desde la lectura de los datos. Por lo tanto, CAP cancela la solicitud de modificación y fija el código de estado 412 (Condición previa fallida) para la respuesta HTTP. El cuerpo de la respuesta contiene un error similar al siguiente:

JSON
12345
"error": { "code": "412", "message": "Precondition Failed", "@Common.numericSeverity": 4 }

Bloqueo pesimista

El bloqueo optimista garantiza la integridad de los datos en caso de modificaciones simultáneas a través de diferentes solicitudes.

Por otro lado, el bloqueo pesimista garantiza la integridad de los datos en caso de modificaciones simultáneas a través de transacciones simultáneas. El bloqueo pesimista le permite bloquear datos para que se bloqueen otras transacciones para que no cambien los datos de ninguna manera.

CAP aprovecha los bloqueos de base de datos para el bloqueo pesimista, mediante el cual se distingue entre bloqueos exclusivos y bloqueos compartidos.

Los registros de datos bloqueados de forma exclusiva no se pueden modificar ni leer mediante otras transacciones. Los bloqueos exclusivos se fijan al leer los registros de datos de la base de datos. La API de consulta de CAP proporciona el método forUpdate() para este fin.

Nota

La construcción y ejecución de consultas se analizará más adelante.

Los bloqueos compartidos también evitan actualizaciones simultáneas mediante transacciones paralelas. Sin embargo, permiten que todas las transacciones lean los registros de datos bloqueados.

Para fijar bloqueos compartidos, la API de consulta proporciona el método forShareLock() .

Los bloqueos adquiridos (ya sean exclusivos o compartidos) se liberan cuando se completa la transacción actual, es decir, comprometidos o rechazados.

Nota

SQLite no admite el bloqueo pesimista.

Demostración y ejercicio: Añadir control de concurrencia optimista

Nota

Como ejercicio, lleve a cabo las instrucciones paso a paso en la siguiente demostración en SAP Business Application Studio.

Como punto de partida para el ejercicio, utilice el resultado del ejercicio anterior Implementar validación de entrada si lo ha completado correctamente. Como alternativa, también puede utilizar la ramificación 8_input_Validation del siguiente repositorio GitHub como punto de partida:

https://github.com/SAP-samples/cap-development-learning-journey

La implementación completa de la simulación se puede encontrar en la rama 9_concurrency_control del repositorio GitHub.

Puede encontrar información detallada sobre el contenido del repositorio y cómo utilizarlo aquí.

Mire el video para ver cómo agregar un optimista control de concurrencia.