¿Cómo se actualiza el valor de los elementos de Amplify Datastore sumando o restando?
Quiero usar Datastore para actualizar un valor basado en el valor actual almacenado en la base de datos. En la documentación se muestra un caso de uso de un contador minorista. Pero, ¿cómo se supone que se debe implementar este tipo de configuración?
Un pequeño ejemplo:
Tengo una tabla de inventario que contiene un artículo y un contador para un artículo:
type Inventory @model {
id: ID!
name: String!
count: Int!
}
Si quiero guardar un nuevo Inventario, puedo hacer esto:
Inventory inventory = Inventory(id, 'product1', 10);
Amplify.Datastore.save(inventory);
Luego, para actualizar, puedo usar Amplify.Datastore.save(inventoryUpdatedModel)
con el mismo ID, y Amplify actualizará el elemento en el almacenamiento. Hasta aquí todo bien.
Entonces, ¿qué pasa si tengo múltiples dispositivos cambiando el mismo valor como en el ejemplo?
Inicio: count = 10;
1: Dispositivo 1 -> Agrega 5 a count (10 + 5 = 15)
2: Dispositivo 2 -> Resta 3 de count (10 – 3 = 7)
3: Ambos dispositivos actualizan Datastore y leen los valores.
Actualmente, solo se muestra el último valor (7 en el ejemplo), donde la respuesta requerida sería 12 (10+5-3=12).
Hasta ahora he intentado:
1) Consultar la base de datos justo antes de guardar, pero esto tiene problemas de concurrencia cuando varios dispositivos realizan operaciones al mismo tiempo.
2) Agregar una nueva tabla llamada updateInventoryCount(inventoryID, numberToAdd), luego procesar los datos en esta tabla uno a la vez, en solo un dispositivo. Ajustar el valor de cualquier actualización al mismo ID y luego eliminarlas funciona, pero no es una solución perfecta.
Lo que me encantaría es algo como Amplify.Datastore.updateValue(ID, -3)
;
Amplify -> Toma el valor antiguo, resta 3, actualiza AppSync con el mismo comando.
davy.ai
Para actualizar un valor en Datastore basado en el valor actual almacenado en la base de datos, sería necesario recuperar el valor actual, actualizarlo con el nuevo valor y luego guardar el valor actualizado de nuevo en la base de datos. Una forma de hacer esto sería utilizar el bloqueo optimista, que es un mecanismo de control de concurrencia que permite que varios usuarios accedan y modifiquen los mismos datos de forma concurrente sin conflictos.
Para implementar el bloqueo optimista en Datastore, puedes utilizar el campo
version
que se genera automáticamente para cada modelo. Cuando recuperas un elemento de la base de datos, el campoversion
contiene la versión actual del elemento. Cuando guardas un elemento actualizado, Datastore compara la versión en el elemento actualizado con la versión en la base de datos. Si coinciden, la operación de guardado se realiza correctamente. Si no coinciden, significa que alguien más ha actualizado el elemento en el ínterin, y Datastore genera unaDataStoreException
con un mensaje de error de conflicto.Para actualizar el recuento de inventario en el ejemplo, puedes recuperar el recuento actual de la base de datos, sumar o restar el nuevo recuento, crear un nuevo objeto
Inventory
con el recuento actualizado y el mismoid
, y luego guardar el objeto actualizado en la base de datos. Aquí tienes un ejemplo de código:Ten en cuenta que el campo
version
se incluye en el objetoInventory
para habilitar el mecanismo de bloqueo optimista. Si laversion
en el elemento actualizado no coincide con laversion
en la base de datos, se generará unaDataStoreException
con un mensaje de conflicto, lo que indica que el elemento ha sido modificado por otro usuario.Utilizando este enfoque, puedes manejar las actualizaciones concurrentes al recuento de inventario de manera segura y confiable, asegurando que las actualizaciones se apliquen correctamente y que los conflictos se resuelvan automáticamente.