Есть ли в приложении Meteor шаблон проектирования для обработки нескольких клиентов, вставляющих одну и ту же логическую запись «одновременно»?
В частности, у меня есть приложение типа скоринга, и несколько клиентов могут создать начальную, в основном пустую, запись Score для участника, когда он готов начать. Затем внешний вид записи используется, чтобы сделать ее доступной на странице для редактирования судьями, увеличения количества штрафов и т. Д.
Stages = new Meteor.Collection("contests");
Entrants = new Meteor.Collection("entrants");
Scores = new Meteor.Collection("scores");
// official picks the next entrant
Scores.insert( stage_id:xxxx, entrant_id:yyyy)
Я доволен последствиями разрешения конфликтов при редактировании записи Score, когда она попадает в Коллекцию. Я не знаю, как поступить с несколькими клиентами, пытающимися вставить Score для пары stage_id / entrant_id.
В синхронном приложении я бы предпочел использовать некоторую форму блокировки или ограничение ключа реляционной БД.
1 ответ
Что ж, согласно этот ответ флаг Meteor $ upsert все еще находится в списке улучшений и, кажется, добавлен в стабильный ветка после выпуска 1.0.
Итак, первый способ - как было сказано добавить уникальный индекс:
Все способы реализации: перечислены здесь. Я бы рекомендовал вам использовать собственные индексы mongo, а не реализацию кода.
Оптимистичный способ параллелизма намного сложнее из-за отсутствия транзакций в MongoDB.
Вот моя реализация (будьте осторожны, может быть ошибка))):
var result_callback = function(_id) {
// callback to call on successfull insert made
}
var $set = {stage_id: xxxx, entrant_id: xxxx};
var created_at = Date.now().toFixed();
var $insert = _.extend({}, $set, {created_at: created_at});
Scores.insert($insert, function(error, _id) {
if (error) {
//handle it
return;
}
var entries = Scores.find($set, {sort: {created_at: -1}}).fetch()
if (entries.length > 1) {
var duplicates = entries.splice(0, entries.length - 1);
var duplicate_ids = _.map(duplicates, function(entry) {
return entry._id;
});
Scores.remove({_id: {$in: duplicate_ids}})
Scores.update(entries[0]._id, $set, function(error) {
if (error) {
// handle it
} else {
result_callback(entries[0]._id)
}
})
} else {
result_callback(_id);
}
});
Надеюсь, это даст вам несколько хороших идей)
К сожалению, предыдущая версия моего ответа была совершенно неверной.
Похожие вопросы
Связанные вопросы
Новые вопросы
meteor
Meteor - это модульная платформа для разработки веб-и мобильных приложений на JavaScript на основе платформы NodeJS.