Na życzenie przedstawiamy zarys naszego problemu i sposobu jego rozwiązania:
W naszym systemie stworzyliśmy niestandardową procedurę blokowania dokumentów (za pomocą funkcji redis-lock), w której następujące zdarzenia miały miejsce w tej dokładnej (nieprawidłowej) kolejności:
NIEPRAWIDŁOWA KOLEJNOŚĆ OPERACJI:
- Otrzymano żądanie klienta
- Dokument zablokowany
- Pobrano dokument
- Dokument edytowany
- Dokument odblokowany
- Żądanie klienta rozwiązane
- Dokument zapisany
Gdy zobaczysz to napisane, problem jest oczywisty:zapisywaliśmy nasze dokumenty poza naszą blokadą dokumentów.
Załóżmy, że #6 w naszym systemie zajmuje 100ms. To jest okno 100 ms, w którym jeśli jakiekolwiek inne żądania przechwycą ten sam dokument, będziemy mieli konflikt zapisywania (zatytułowany błąd w tym pytaniu jest w zasadzie konfliktem zapisywania IMHO).
Innymi słowy/przykład:w naszym systemie Request A pobrał dokument X w wersji 1, edytował go, a następnie odblokował, ale zanim Request A zapisał dokument, Request B pochwycił dokument X i zwiększył go do wersji 2 (czytaj na Mongo wersje, aby uzyskać więcej informacji na ten temat). Następnie Request A rozwiązuje swoje żądanie Klienta i przechodzi do zapisania dokumentu X, ale próbuje zapisać wersję 1, a teraz widzi, że ma wersję 2, a więc powyższy błąd.
Więc naprawa jest łatwa. Zapisz swoje dokumenty w swoim zamku. (W powyższym przykładzie przesuń #7 do przed #5. Zobacz poniżej.)
WŁAŚCIWA/STAŁA KOLEJNOŚĆ OPERACJI
- Otrzymano żądanie klienta
- Dokument zablokowany
- Pobrano dokument
- Dokument edytowany
- Dokument zapisany
- Dokument odblokowany
- Żądanie klienta rozwiązane
(Możesz argumentować, że #6 i #7 powinny zostać zamienione, ale jest to poza zakresem Mongo/Mongoose/tego pytania.)
Zostawię to pytanie na chwilę bez odpowiedzi i zobaczę, czy ktoś może rzucić trochę światła na lepszy sposób na odizolowanie odpowiedniego kodu i rozwiązanie tego problemu. W naszym przypadku był to bardzo systemowy problem i BARDZO trudny do rozwiązania dla naszego poziomu umiejętności w tym czasie.