вот в каком вопросе...
Проблема такая, есть сервис на go, запускается скажем в 10 потоков (может сильно больше).
Каждый сервис обрабатывает файл, и нужные данные из него собирает в документ,
а дальше документ вставляет в коллекцию в mongoDB.
У документов есть номер и версия, и перед тем как вставить в монгу, делается запрос по номеру документа.
Если документа нет - идет вставка.
Если есть - сравниваются версии,
если у нового документа версия больше, чем у документа в монге - документ в монге заменяется новым документом (с большей версией).
Но из-за параллельной работы сервисов получается так, что например в нескольких работающих сервисах, одновременно обрабатывается документ с одним и тем же номером,
но разными версиями.
И при поиске (запрос в монгу) все сервисы получают, что документа с таким номером нет,
и все 3 сервиса добавляют один и тот же документ но с разной версией.
пробовал на mongo 4.0, 4.2, 5
Пробовал replaceOne
Индекс есть на номер документа
Пробовал транзакции, не спасают, с разницей от 1 до 150 мс вижу в дате создания документа в коллекции.
Вот собственно вопрос, что можно еще сделать/попробовать чтоб не было дублей в монге при многопоточной работе сервисов? может я в поисках своих что-то упустил?
привет. что нибудь нашли дельное по своему вопросу?
Привет, нет :( задача перешла в пассивный поиск, но решение очень нужно!
а триггеры на обновление, вставку не пробовали?
Нет, что-то мне не попалось даже такое Спасибо за наводку, почитаю про них!!!
поставить уникальный индекс на номер документа и тогда не будет дублей, все остальное либо транзакции либо upsert при условии что версия дока в базе меньше
если вы пишите что появляются дубли - значит нет
а кстати ведь да, верно подмечено!!!
Всем привет, не большой апдейт к моему старому вопросу... - По предложению @wayfar8r: Триггеры решили не использовать - По предложению @yatoba: 1."поставить уникальный индекс на номер"... он и правда был но не на уникальность :/ добавил... В этом случае дублей нет, но после обработки задания - находились документы не самой последней версии. 2."все остальное либо транзакции либо upsert при условии что версия дока в базе меньше" (пробовал без уникального индекса) *транзакции - не помогли (дубли находятся), либо их как-то особым образом надо настраивать по части блокировок (возможно недораскурил) и плюс еще получал ошибку (WriteConflict) Plan executor error during findAndModify :: caused by :: WriteConflict error: this operation conflicted with another operation. Please retry your operation or multi-document transaction. Пробовал с опциями по дефолту и с опциями Majority так: sc.StartTransaction(options.Transaction(). SetReadConcern(readconcern.Majority()). SetWriteConcern(writeconcern.New(writeconcern.WMajority())), ) Подсматривал сюда https://github.com/mongodb/mongo-go-driver/blob/v1.9.1/examples/documentation_examples/examples.go не победил ( *upsert - Тоже дубли (пробовал без уникального индекса) Примерный код был таков: mongo.Client.UseSession(cx, func(sc mongo.SessionContext) error { ... opts := options.Replace().SetUpsert(true) result, err := collection.ReplaceOne(sc, query, obj, opts) ... }) Может еще у кого будут идеи? - И на этом вопросе опять хотел остановится. но решил попробовать все в раз применить: уникальный индекс + транзакция c Majority-опциями + replaceOne с upsert:true => x10 потоков и кажется все получилось, дублей понятно нет, но и неактульных версий с ходу не нашел (долго проверять) Может кто чего дополнит/поправит? :) CLUSTER Mongos EDITION MongoDB 5.0.8 Community Всем откликнувшимся спасибо за советы!
Обсуждают сегодня