Создайте атомарную хранимую процедуру / хранимую JS с MongoDB

Нам нужно создать атомарную процедуру в нашей базе данных MongoDB.

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

Как я могу создать хранимую JS или хранимую процедуру в MongoDB, которая может выполнять всю процедуру атомарно?

Я вижу некоторую информацию, но ничего не выглядит особенно ясным для меня:

Вызвали сохраненную функцию javascript из Mongoose?

https://groups.google.com/forum/#!topic/mongoose-orm/sPN3wfDstX4

https://github.com/mongoosejs/mongoose-function

Где я могу найти полезную информацию о том, как на самом деле написать атомарную/блокирующую хранимую процедуру, которая выполняется в MongoDB, и как на самом деле вызвать хранимую процедуру из приложения?


person Alexander Mills    schedule 25.07.2017    source источник
comment
В mongodb нет такой вещи, как атомарная/блокирующая хранимая процедура. То, что вы хотите сделать, может быть возможным с findAndModify, но это а) действительно трудно сказать, учитывая, насколько расплывчато ваше описание и б) атомарно только на уровне документа.   -  person Sergio Tulentsev    schedule 25.07.2017
comment
@SergioTulentsev, это вовсе не расплывчатый вопрос, я точно описал, что я хочу сделать :) Ну, что я хочу сделать более точно, так это создать хранимую процедуру, которая может создать блокировку документа и удерживать блокировку для время жизни хранимой процедуры.   -  person Alexander Mills    schedule 25.07.2017
comment
Ага, не получится :)   -  person Sergio Tulentsev    schedule 25.07.2017
comment
да, похоже, вы правы, это большой недостаток MongoDB, что за PoS :) Мне нужен механизм блокировки.   -  person Alexander Mills    schedule 25.07.2017
comment
Хорошо, Серджио, вы можете сделать это так (с индексами TTL): speakerdeck.com/raindev /распределенная-блокировка-с-mongodb   -  person Alexander Mills    schedule 25.07.2017
comment
Но это дерьмовый механизм, потому что вам нужно повторить попытку/опрос, чтобы получить блокировку. Но это сработает, если вам это действительно нужно.   -  person Alexander Mills    schedule 25.07.2017
comment
Так что я просто собираюсь сказать это: вы были неправы! :)   -  person Alexander Mills    schedule 25.07.2017
comment
Я написал это, если вам интересно - github.com/ORESoftware/live-mutex   -  person Alexander Mills    schedule 25.07.2017
comment
Я мог бы в конечном итоге использовать его вместо индексов TTL в MongoDB, посмотрим.   -  person Alexander Mills    schedule 25.07.2017
comment
Это блокировка уровня приложения. Любой клиент волен игнорировать его и обновлять коллекцию по своему желанию. Это бесполезно :)   -  person Sergio Tulentsev    schedule 25.07.2017
comment
Это правильно, но все, что мне нужно, это блокировка на уровне приложения. Я могу войти в серверную и разбить оборудование бейсбольной битой, если захочу. Конечно, необходимо соблюдать некоторые правила.   -  person Alexander Mills    schedule 25.07.2017
comment
Я предполагаю, что существует гораздо больше случаев, когда необходима блокировка на уровне приложения, чем блокировка на уровне базы данных, не так ли? Я не могу думать о необходимости блокировки уровня базы данных.   -  person Alexander Mills    schedule 25.07.2017
comment
В реальной базе данных ACID вам не нужно соглашаться следовать правилам. Правила соблюдаются базой данных. Просто говорю. :) Если это сработает для вас, то отлично, моя работа здесь выполнена :)   -  person Sergio Tulentsev    schedule 25.07.2017
comment
Что ж, если бы у меня был свой путь, мы бы использовали РСУБД вместо MongoDB, но это был не мой выбор, в любом случае спасибо за вашу помощь.   -  person Alexander Mills    schedule 25.07.2017
comment
@sergio, если вы добавите ответ, в основном резюмирующий то, что вы здесь сказали, я проголосую, возможно, в какой-то момент помогу кому-то еще   -  person Alexander Mills    schedule 02.08.2017


Ответы (1)


(резюмируя комментарии выше)

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

Лучшая атомарная вещь, которую может предложить mongodb, — это findAndModify . Его атомарность, естественно, ограничена только одним документом, и у вас есть довольно ограниченный список операторы обновления (то есть вы даже не можете использовать поля документа, как и обычные обновления).

Это в некоторой степени возможно с помощью блокировки на уровне приложения: приложение вставляет или изменяет специальный документ блокировки, который сигнализирует другим частям приложения: "Я использую/обновляю это, пожалуйста, воздержитесь от касания Это". После завершения операции приложение снимает блокировку, так что теперь ее может снова получить кто-то другой. Конечно, это зависит полностью от субъектов, соблюдающих соглашения о блокировках, что, мягко говоря, не очень надежно.

person Sergio Tulentsev    schedule 02.08.2017
comment
Индексы TTL работают для блокировки с MongoDB, но я не знаю, насколько хорошо они действительно работают. - person Alexander Mills; 02.08.2017
comment
@AlexanderMills: индекс TTL (в колоде слайдов, на которую вы ссылаетесь) существует только для обеспечения снятия блокировки, если по какой-либо причине ваша программа дает сбой, прежде чем она сможет нормально снять блокировку. Кроме этого, они не имеют никакого отношения к блокировке. - person Sergio Tulentsev; 02.08.2017
comment
Нет, неправда, держатель блокировки получает блокировку, устанавливая индекс с помощью ttl, когда блокировка завершена, держатель блокировки удаляет индекс, системе не нужно ждать до истечения срока действия индекса. Другие запросчики блокировки используют опрос для получения блокировки , они получают блокировку, когда успешно создают индекс, а по завершении удаляют его. ttl — это просто критическая функция, необходимая, если приложение выходит из строя. Это дрянная система блокировки, потому что она требует большого количества опросов, но она будет работать. - person Alexander Mills; 02.08.2017
comment
@AlexanderMills: что вы имеете в виду, когда они создают индекс? Уверяю вас, в этом сценарии индексы не создаются и не удаляются динамически во время выполнения. :) - person Sergio Tulentsev; 02.08.2017
comment
индекс удаления, docs.mongodb.com/manual/reference/method/ - person Alexander Mills; 02.08.2017
comment
это TTL, это важная функция, как я уже сказал - person Alexander Mills; 02.08.2017
comment
так что вы используете коллекцию под названием Locks, вы можете добавить столько индексов, сколько хотите, и удалить столько, сколько хотите. вы можете создавать индексы динамически :) - person Alexander Mills; 02.08.2017
comment
@AlexanderMills: да, теоретически можно. Тем не менее, в этом сценарии (из слайд-колоды) вы не добавляете/удаляете какие-либо индексы. Вы создаете индекс TTL один раз и больше никогда его не трогаете. - person Sergio Tulentsev; 02.08.2017
comment
@AlexanderMills: вы, возможно, думаете, что индекс TTL - это индекс, который самоуничтожается по истечении времени ожидания? - person Sergio Tulentsev; 02.08.2017
comment
извините, я пытался вспомнить реализацию - это не то, что мы создаем/удаляем индексы волей-неволей, мы создаем/удаляем документы, которые представляют собой блокировки, и индекс ttl гарантирует, что он в конечном итоге будет удален. - person Alexander Mills; 02.08.2017
comment
@AlexanderMills: да, с этим я могу согласиться. - person Sergio Tulentsev; 02.08.2017