Par demande, voici un aperçu de notre problème et comment nous l'avons résolu :
Dans notre système, nous avons créé une routine de verrouillage de document personnalisée (à l'aide de redis-lock), dans laquelle les événements suivants se sont produits dans cet ordre précis (incorrect) :
ORDRE INCORRECT DES OPÉRATIONS :
- Demande client reçue
- Document verrouillé
- Document récupéré
- Document modifié
- Document déverrouillé
- Demande client résolue
- Document enregistré
Une fois que vous l'avez vu écrit, le problème est évident :nous enregistrions nos documents en dehors de notre verrou de document.
Supposons que # 6 prend 100 ms dans notre système. Il s'agit d'une fenêtre de 100 ms dans laquelle si d'autres requêtes saisissent le même document, nous allons avoir un conflit de sauvegarde (l'erreur intitulée dans cette question est essentiellement un conflit de sauvegarde à mon humble avis).
En d'autres termes/exemple :dans notre système, la requête A a récupéré la version 1 du document X, l'a modifiée, puis l'a déverrouillée, mais avant que la requête A n'enregistre le document, la requête B a saisi le document X et l'a incrémenté à la version 2 (lire sur Mongo versions pour plus d'informations à ce sujet). Ensuite, la demande A résout sa demande client et va enregistrer le document X, mais elle essaie d'enregistrer la version 1, et maintenant elle voit qu'elle a la version 2, et donc l'erreur ci-dessus.
La solution est donc facile. Enregistrez vos documents à l'intérieur de votre serrure. (Dans l'exemple ci-dessus, déplacez le #7 avant le #5. Voir ci-dessous.)
ORDRE CORRECT/FIXE DES OPÉRATIONS
- Demande client reçue
- Document verrouillé
- Document récupéré
- Document modifié
- Document enregistré
- Document déverrouillé
- Demande client résolue
(Vous pourriez faire valoir que #6 et #7 devraient être échangés, mais cela sort du cadre de Mongo/Mongoose/cette question.)
Je vais laisser cette question sans réponse pendant un moment et voir si quelqu'un peut faire la lumière sur une meilleure façon d'isoler le code pertinent et de résoudre ce problème. Dans notre cas, il s'agissait d'un problème très systémique et TRÈS difficile à résoudre pour notre niveau de compétence à l'époque.