По заявка ето описание на нашия проблем и как го разрешихме:
В нашата система създадохме персонализирана рутина за заключване на документи (използвайки redis-lock), при която следното се случи в този точен (неправилен) ред:
НЕПРАВИЛЕН РЕД НА ОПЕРАЦИИ:
- Получена е клиентска заявка
- Документът е заключен
- Документът е извлечен
- Документът е редактиран
- Документът е отключен
- Заявката на клиента е разрешена
- Документът е запазен
След като го видите написано, проблемът е очевиден:ние записвахме нашите документи извън нашия документ за заключване.
Да приемем, че #6 отнема 100 мс в нашата система. Това е прозорец от 100 ms, в който ако други заявки грабнат същия документ, ще имаме конфликт при запазване (заглавената грешка в този въпрос е основно конфликт на запазване IMHO).
С други думи/пример:в нашата система, Заявка A грабна версия 1 на Документ X, редактира я, след това я отключи, но преди Заявка A да запази документа, Заявка B грабна Документ X и го увеличи до Версия 2 (прочетете на Mongo версии за повече информация за това). След това Заявка A разрешава своята клиентска заявка и отива да запази документ X, но се опитва да запази версия 1 и сега вижда, че има версия 2, и по този начин грешката по-горе.
Така че поправката е лесна. Запазете вашите документи в ключалката си. (В горния пример преместете #7 преди #5. Вижте по-долу.)
ТОЧЕН/ФИКСИРАН РЕД НА ОПЕРАЦИИ
- Получена е клиентска заявка
- Документът е заключен
- Документът е извлечен
- Документът е редактиран
- Документът е запазен
- Документът е отключен
- Заявката на клиента е разрешена
(Бихте могли да аргументирате, че #6 и #7 трябва да бъдат разменени, но това е извън обхвата на Mongo/Mongoose/този въпрос.)
Ще оставя този въпрос без отговор за известно време и ще видя дали някой може да хвърли малко светлина върху по-добър начин за изолиране на съответния код и отстраняване на този проблем. В нашия случай това беше много системен проблем и МНОГО предизвикателство за отстраняване на неизправности за нашето ниво на умения по това време.