2015-05-12 9 views
1

Постановка задачиПараллельное обновление одной и той же коллекции же документа

Как обрабатывать одновременные команды обновления на той же коллекции и того же документа.

тока DB Структура

EDIT - Изменена структура

{ 
    "userId":1, 
    "summary_extra":[ 
     { 
      "some_id":1, 
      "names":[ 
       "one", 
       "two" 
      ] 
     }, 
     { 
      "some_id":2, 
      "names":[ 
       "three", 
       "four" 
      ] 
     } 
    ] 
    }, 
    { 
    "userId":2, 
    "summary_extra":[ 
     { 
      "some_id":1, 
      "names":[ 
       "one", 
       "two" 
      ] 
     }, 
     { 
      "some_id":2, 
      "names":[ 
       "three", 
       "four" 
      ] 
     } 
    ] 
    } 

Если один пользователь пытается обновить в то время, то существует обыкновение быть никаких проблем, чтобы обновить документ. Но если есть несколько пользователей (с вероятностью 10, минимум), то как я могу обновить один и тот же документ.

Что мне делать в этих сценариях ??

N: B Данные являются точными, но точно такими же структурами, которые у меня есть.

EDIT: Теперь я думаю, что могу одновременно обновлять два разных документа в одних и тех же коллекциях несколькими пользователями?

+1

Категорически, вы должны разработать * некоторые * способы, чтобы предотвратить обновление двух пользователей одним и тем же документом или, если это имеет смысл в вашей ситуации, разрешить различные обновления действовать без конфликтов. Вы можете сообщить другим пользователям: «Извините, но этот документ сейчас обновляется кем-то другим». В противном случае у вас должен быть какой-то надежный способ слияния двух наборов изменений (независимо от того, как теперь может существовать «устаревшая» версия данных пользователя), или сообщить им: «Извините, но кто-то еще обновил . Попробуй еще раз." –

+0

Ключевой момент: ваша реализация должна отражать «то, что имеет смысл для * конечного пользователя, * с точки зрения его или ее». Это должно быть удобно, разумно и, прежде всего, должно обеспечить, чтобы каждый мог четко знать, что содержит документ, не наступая на пальцы друг друга или не разбивая документ. Считайте «пример использования» очень осторожным, с точки зрения конечного пользователя. –

+0

Если бы вы отправили эти комментарии в качестве ответа, я бы дал вам upvote;) – mhlz

ответ

2

Вы можете включить поле версии, которое будет увеличиваться с каждым обновлением (это будет еще один $ inc в вашем обновлении и фильтр запроса). Затем, если кто-то обновил документ от версии, у вас есть, обновления не могут пройти. Если вы используете Morphia, аннотация @Version позаботится об этом для вас прозрачно.

+0

«Версии» - отличное предложение. Вместо постоянного обновления * той же * записи вы (в рамках транзакции базы данных ...) создаете новую * копию *, с добавленным «номером версии». Возможно, запись также несет в себе номер версии, из которой она была создана. Теперь нет никакой возможности конфликта, потому что каждая «обновленная копия» является, по сути, * новым * одним ... и как «старые», так и «новейшие» постоянно доступны. Даже если два пользователя сделали конфликтующие изменения, у вас есть точная запись обеих сессий и можно * надежно * исправить ее (в другую новую версию). –

+0

Кстати, есть системы баз данных, такие как Firebird, которые принципиально используют эту технику вместо традиционных «транзакций». (Они * реализуют * «традиционные транзакции» таким образом, но реализация имеет очень разные эффекты параллелизма. Долгосрочные задания отчета с большими phat-запросами * не * вызывают блокировки узких мест.) –

+0

Верфирование Morphia не создает новые копии документов, хотя я написал расширение, которое делает это: https://github.com/evanchooly/lariat – evanchooly

Смежные вопросы