Per ogni richiesta, ecco uno schema del nostro problema e come lo abbiamo risolto:
Nel nostro sistema abbiamo creato una routine di blocco dei documenti personalizzata (usando redis-lock), in cui si è verificato quanto segue in questo preciso (errato) ordine:
ORDINE DELLE OPERAZIONI ERRATO:
- Richiesta cliente ricevuta
- Documento bloccato
- Documento recuperato
- Documento modificato
- Documento sbloccato
- Richiesta del cliente risolta
- Documento salvato
Una volta che lo vedi scritto, il problema è evidente:stavamo salvando i nostri documenti al di fuori del nostro Blocco documenti.
Supponiamo che il numero 6 richieda 100 ms nel nostro sistema. Questa è una finestra di 100 ms in cui se altre richieste catturano lo stesso documento, avremo un conflitto di salvataggio (l'errore intitolato in questa domanda è fondamentalmente un conflitto di salvataggio IMHO).
In altre parole/esempio:nel nostro sistema, la Richiesta A ha afferrato la Versione 1 del Documento X, l'ha modificata, quindi sbloccata, ma prima che la Richiesta A salvasse il Documento, la Richiesta B ha afferrato il Documento X e l'ha incrementato alla Versione 2 (leggi su Mongo versioni per maggiori informazioni al riguardo). Quindi la richiesta A risolve la sua richiesta del cliente e va a salvare il documento X, ma sta cercando di salvare la versione 1 e ora vede che ha la versione 2, e quindi l'errore sopra.
Quindi la soluzione è facile. Salva i tuoi documenti all'interno della tua serratura. (Nell'esempio sopra, sposta #7 prima di #5. Vedi sotto.)
ORDINE DELLE OPERAZIONI CORRETTO/FISSO
- Richiesta cliente ricevuta
- Documento bloccato
- Documento recuperato
- Documento modificato
- Documento salvato
- Documento sbloccato
- Richiesta del cliente risolta
(Potresti argomentare che il numero 6 e il numero 7 dovrebbero essere scambiati, ma questo non rientra nell'ambito di Mongo/Mongoose/questa domanda.)
Lascerò questa domanda senza risposta per un po' e vedrò se qualcuno può fare luce su un modo migliore per isolare il codice pertinente e risolvere questo problema. Nel nostro caso, questo era un problema molto sistemico e MOLTO difficile da risolvere per il nostro livello di abilità in quel momento.