Я разрабатываю одностраничное веб-приложение, которое будет использовать базу данных документов NoSQL (например, MongoDB), и я хочу генерировать события, когда я изменяю свои сущности.
Поскольку большинство этих баз данных поддерживают транзакции только на уровне документа (MongoDB только что добавил поддержку ASIC), нет хорошего способа сохранить изменения в одном документе, а затем сохранить события этих изменений в других документах.
Скажем, например, что у меня есть коллекция «События» и коллекция «Карты», как у Trello.Когда я изменяю описание карты из коллекции «Карты», должно генерироваться событие «CardDescriptionChanged».
Проблема в том, что в случае сбоя или какой-либо ошибки между сохранением изменений в коллекции 'Cards' и добавлением события в коллекцию 'Events' это событие не будет сохраняться, и я не хочучто.
Я провел некоторое исследование по этой проблеме, и большинство людей предложили бы использовать один из нескольких подходов:
Не используйте MongoDB, используйте SQLвместо базы данных (я не хочу этого)
Использовать источник событий.(Это создает сложность, и я хочу очистить старые события в какой-то момент, поэтому я не хочу сохранять все события в памяти. Теперь я могу использовать моментальные снимки и удалять более старые события из точки моментального снимка, но в этом есть сложностьрешение)
Поскольку ошибки такого рода, вероятно, не будут происходить слишком часто, просто игнорируйте их и рискуйте иметь события, которые не будут сохранены (я тоже этого не хочу)
Использовать процессор событий / команд / действий.Сохраните команды / действия, такие как «ChangeCardDescription», и используйте процессор, который будет их обрабатывать и обновлять сущности.
Я рассмотрел вариант 4, но возникает пара вопросов:
- Как мне управлять параллелизмом?
Я могу поставить в очередь все команды для одной и той же сущности (например, карты или платы) и убедиться, что они обрабатываются последовательно, а события для разных сущностей (разных карточек) могут обрабатываться параллельно.Тогда я могу использовать обработанные команды как события.Одна проблема здесь состоит в том, что изменения в объекте могут генерировать несколько событий, которые могут не соответствовать одной команде.Мне придется разбивать на очень мелкозернистые команды все действия пользователя, чтобы я мог затем преобразовать их в события.
- Сообщения об ошибках и обработка ошибок.
Если этот процесс асинхронный, я должен управлять сообщением об ошибках клиенту.А также я должен удалить или пометить команды, которые потерпели неудачу.
- У меня все еще есть проблема с маркировкой команд как обработанных, так как нет транзакций.Я знаю, что для решения этой проблемы мне нужно сделать обработку команд идемпотентной.
Поскольку Trello использует MongoDB и генерирует действия ('DeleteCardAction', 'CreateCardAction') с изменениями сущностей (Cards, Boards ..)) Мне было интересно, как они решают эту проблему?