¿Cómo maneja una aplicación que se ejecuta en múltiples dispositivos con solicitudes de usuario en conflicto? Por ejemplo, guardar un solo proyecto con contenido diferente.

Existen múltiples formas de tratar las solicitudes de usuarios en conflicto. El método que elija simplemente depende de para qué son los datos y cuál es el resultado que desea.

El primer y más simple método es ignorar el problema . Ambos dispositivos enviarán la solicitud, y el que se procesa más adelante anula el primero. Su resultado final será simplemente la transacción que se ejecutó por última vez. Los servidores de archivos simples funcionan de esta manera.

Un segundo método es usar el bloqueo pesimista. Antes de hacer cualquier cambio, el dispositivo dice “Hola, modificaré este recurso, nadie lo toque”. Luego, el usuario realiza el cambio y luego lo confirma. Cuando se compromete el cambio, también dice “Ya terminé”. Supongamos que dos dispositivos intentan bloquear el mismo recurso, uno de ellos recibirá un error que dice “alguien ya tiene este recurso, intente nuevamente más tarde” o simplemente cuelgue hasta que se libere el bloqueo. Algunos ejemplos de esto son sharepoint, Visual Source Safe, Clearcase.

Un tercer método es usar un bloqueo optimista. Cuando el dispositivo obtiene una copia del recurso, incluye un número de versión. El dispositivo realiza un cambio, aumenta el número de versión y envía el cambio con el nuevo número de versión. La transacción se acepta solo si el nuevo número de versión es mayor que el actual. Por ejemplo:

  1. el dispositivo A obtiene el recurso en la versión 1,
  2. el dispositivo B obtiene el mismo recurso en la versión 1.
  3. El dispositivo A realiza algunos cambios y envía la actualización con la versión 2.
  4. El servidor acepta los cambios porque la versión 2 es mayor que la versión 1 que tiene actualmente.
  5. El dispositivo B realiza algunos otros cambios e intenta enviar la actualización con la versión 2.
  6. El servidor ve que ya tiene una versión 2 y esta actualización también tiene la versión 2. Por lo tanto, el servidor rechaza la transacción y le dice al Dispositivo B que intente nuevamente o falle.

Algunos ejemplos de esto incluyen CVS, Subversion, Git, etc.

Las bases de datos relacionales pueden usar un bloqueo optimista o pesimista.

Este es un problema antiguo y difícil de resolver completamente correcto, al menos a través de la automatización sin intervención humana.

Una respuesta simplista es “el último escritor gana”.

Pero, ¿qué pasa si el último escritor contiene solo un cambio trivial que luego sobrescribe el trabajo extenso de un escritor anterior (sin haber leído primero esa versión)?

Otra estrategia común ha sido simplemente “preguntar al usuario” (quién está haciendo el cambio conflictivo; aunque esto, por supuesto, funciona, requiere mucha mano de obra y puede conducir a más errores, o en muchos casos simplemente alienta al usuario a guardar múltiples versiones incompatibles del mismo archivo (con diferentes nombres).

Active Directory, documentos de Google y algunos sistemas de control de versiones, intentan guardar a un nivel más granular, de modo que al menos los conflictos se mantengan al mínimo, y muchas veces simplemente se evitan.

Active Directory (dominios de Microsoft) guarde en el nivel de PROPIEDAD, por lo que si una persona cambia la “dirección” de los usuarios mientras otra actualiza el “número de teléfono” de los usuarios, ambos cambios se mantendrán porque simplemente NO HAY CONFLICTO.

(Por supuesto, esto mueve el problema al nivel de propiedad, pero los conflictos a este nivel son más raros, y el “último escritor” es más probable que sea correcto para propiedades tan simples en cualquier caso).

Los documentos de Google permiten que varios usuarios (a través de la red) cambien una hoja de cálculo; cada uno verá los cambios realizados en las celdas por el otro usuario casi en tiempo real, por lo que los conflictos serios son poco frecuentes.

El control de revisión y la fusión se conocen bien. Una de las mejores implementaciones disponibles gratuitamente está en Git: Fusión avanzada

Esperemos que haya un mecanismo de bloqueo para cualquier cosa con un estado persistente. Puede haber múltiples bloqueos de solo lectura, pero solo un bloqueo de lectura / escritura. Este es un problema muy general para cualquier situación en la que haya múltiples hilos de ejecución simultánea.