Как предотвратить вставку нескольких горутин в коллекции людей, если уже существует человек с таким же именем и фамилией?

Как запретить нескольким горутинам вставлять документ в коллекции людей, если уже существует человек с таким же именем и фамилией?

type Person struct {

    Id                      bson.ObjectId   `bson:"_id"`
    Name            string          `bson:"name"`
    LastName            string          `bson:"lastName"`

}

Я использую Mongo с драйвером mgo для языка go.

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


person PaolaJ.    schedule 25.05.2015    source источник
comment
это помогает начать писать код.   -  person Salvador Dali    schedule 25.05.2015
comment
@SalvadorDali Я пытаюсь найти перед вставкой, есть ли документ с таким же именем и фамилией, но я не думаю, что это охватывает весь случай, когда обе горутины проверяются одновременно. Я пробовал обеспечить индекс по двум полям (имя, фамилия), но это также не помогло   -  person PaolaJ.    schedule 25.05.2015
comment
@ПаолаДж. Я не видел ваш последний комментарий, когда я опубликовал свой ответ. Я пытался обеспечить индексирование по двум полям (имя, фамилия), но это также не помогло Не могли бы вы показать, как вы создали свой индекс и как вам удалось вставить два документа с одним и тем же (name, lastName)̀ ?   -  person Sylvain Leroux    schedule 25.05.2015


Ответы (1)


Как запретить нескольким goroutines/process/thread/applications/... вставлять документы в коллекции людей, если уже существует человек с таким же именем и фамилией

Единственный способ предотвратить дублирование записей, особенно. в параллельной среде используется уникальный индекс для {name:1, lastname:1}. Затем в своем коде вы должны быть готовы изящно обработать исключение, вызванное потенциальным столкновением.

Никогда никогда не выполняйте проверку перед вставкой, так как в MongoDB у вас нет транзакции, поэтому вполне возможно, что запись была одновременно вставлена ​​другим клиентом после вашего < em>check и перед insert.


Другие люди, безусловно, могут помочь вам с правильным синтаксисом Go, но что-то вроде строк следующего кода (заимствовано из здесь) позволит вам создать нужный индекс:

index := mgo.Index{
Key: []string{"name", "lastName"},
Unique: true,
}

err = c.EnsureIndex(index)

Затем каждый раз, когда вы вставляете документ, вам нужно использовать функцию mgo.isDup. чтобы проверить, не была ли ошибка вызвана дублирующимся ключом. В качестве примера из предыдущего ответа @elithrar:

err := users.Insert(user) // where user is type *mgo.Collection
if err != nil {
    if mgo.IsDup(err) {
        // Is a duplicate key, but we don't know which one 
    }
    // Is another error
}
person Sylvain Leroux    schedule 25.05.2015
comment
@Sylvain Leroux Должен ли я вызывать это только один раз, в основной или в функции инициализации, правильно? - person PaolaJ.; 25.05.2015
comment
@ПаолаДж. Я отредактировал ответ, чтобы предоставить дополнительную информацию и указатели на некоторую связанную документацию. Но поскольку я не специалист по Go, другие ответы могут содержать больше деталей, чем я могу предоставить. - person Sylvain Leroux; 25.05.2015