Это ошибка в MongoRepository Spring Boot 2.2 или ожидаемое поведение? - PullRequest
0 голосов
/ 04 февраля 2020

Я столкнулся с чем-то, чего я не обязательно ожидал, но также не могу сразу вызвать ошибку на одном дыхании. Я разрабатываю сервис Spring Boot (2.2), который извлекает сообщения из очередей RabbitMQ и сохраняет фрагменты данных в документах, которые сохраняются в MongoDB. В одном сценарии у меня есть два потребителя, каждый из которых извлекает заказ, добавляет уникальную квитанцию ​​как вложенный документ в документ заказа, а затем сохраняет изменения обратно в коллекцию заказов.

Это прекрасно работает при нормальной рабочей нагрузке сценарий ios, потому что два потребителя вряд ли будут работать в одном и том же порядке в такой короткий промежуток времени (если потребители не играют в догонялки после восстановления после падения в течение некоторого периода времени.) Однако; Мои интеграционные тесты показали, что эти два потребителя фактически перезапишут друг друга, если они оба попытаются обновить один и тот же заказ в короткие сроки.

Пример:

  1. В MongoDB существует заказ 123 без поступлений
  2. Потери потребителя 1 Заказ 123
  3. Потери потребителя 2 Заказ 123
  4. Потребитель 1 добавляет квитанцию ​​и сохраняет заказ
  5. Потребитель 2 добавляет квитанцию ​​и сохраняет заказ
  6. Только квитанция, добавленная потребителем 2, сохраняется в коллекции вместе с документом

Я прибегнул к объединению распределенной блокировки по номеру заказа, чтобы избежать конфликта, поэтому я не обязательно ищу решения для довольно сложной проблемы параллелизма.

Мой реальный вопрос касается того, является ли это ожидаемым поведением. С одной стороны, кажется довольно очевидным, что поле квитанции с документом заказа будет просто «обновлено» в соответствии с текущим состоянием хранилища. Тем не менее, кажется, что есть возможность избежать этой проблемы, генерируя соответствующие команды MongoDB для преобразования добавлений / обновлений / удалений во вложенные массивы документов в уровень персистентности с меньшей грубой силой.

Может кто-нибудь прояснить, почему это работает так, как работает? Я разрываюсь между «это MongoDB, а не реляционная база данных - пустышка» и тем фактом, что внутреннее требование к репозиторию c заключается в том, чтобы он был способен точно передавать инструкции персистентности для хранения отдельных агрегатов в контексте агрегата root.

...