2013-09-08 4 views
1

Допустим, у меня есть коллекция с полями views_count, males_views_count и females_views_count. Я хотел бы иметь возможность $inc (приращение) полей счетчика соответственно при просмотре страницы.Понимание атомных операций и условий гонки

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

Я читал об атомных операциях в Мондомбе. Там, где они, как правило, имеют успех или неудачу. Запись записана, или нет. Означает ли это, что мне нужно создать логику, чтобы определить, завершилась ли операция, и если да, повторите попытку?

Возвращаясь к моему сценарию. Что делать, если я хотел бы сделать каждый просмотр (даже при возникновении условий гонки). Я знаю, что замки Мондобба немного отличаются от традиционных РСУБД ». Как правило, я бы использовал оптимистичную технологию блокировки. Аналогично:

begin 
    # .. do work .. determine if user is a male or a female 
    stat.save 
rescue StaleDocumentError 
    stat.reload 
    retry 
end 

Или атомарные операции предназначены для предотвращения гонки условий, как это сервер, который делает обновление и авторитетно о том, что правда есть? Если это так, нам еще нужно реализовать оптимистичные/пессимистические методы блокировки, или Монгодб позаботится об этом для нас, если мы будем использовать атомные операции?

+0

$ inc является атомарным, никакое состояние гонки не будет происходить, с атомными операциями (как и со многими другими вещами) только одна операция в данный момент может выполняться на документе, а серверный неврр выбирает состояние частичного документа, только один после или перед операцией – Sammaye

+0

Если одна атомная операция попадает в «устаревшую запись», что с ней происходит? Выполняет ли операция повторную/повторную очередь? Или операция потеряна (запись не сохраняется)? –

+0

Это никогда не ударит по устаревшей записи, это невозможно, сервер никогда не будет выбирать частичный документ, и, поскольку атомные операции, как говорит стэнни, запускаются в очереди, вы никогда не получите устаревший документ. – Sammaye

ответ

2

Если вы используете атомные операции, такие как $inc, состояние гонки не существует. Если у вас есть два приращения из разных потоков, они будут применяться в порядке, полученном сервером, и конечный результат в документе будет таким же после применения обеих операций.

Если вы обновляете поля до определенных значений с помощью $set, то «выигрышное» значение будет использовано последним $set. Если случай использования вашего приложения может привести к конфликтующим обновлениям одного и того же поля, тогда будет полезно оптимизировать блокировку/управление версиями.

Что касается обработки исключений, вы должны предположить, что любая операция базы данных может потенциально привести к исключению сервера (сетевая ошибка, дубликат ключа ...) и повторить попытку. Для атомных обновлений или неатомных обновлений не требуется специальной логики, если вы не решите реализовать свою оптимистичную блокировку (в этом случае вы, вероятно, сможете восстановить текущую версию документа и повторить операцию).

Руководство MongoDB охватывает несколько разных моделей в Isolate Sequence of Operations.