Firestore: запуск транзакции для трех лучших пользователей в коллекции - PullRequest
0 голосов
/ 03 августа 2020

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

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

Я не уверен, как добиться этого с помощью транзакции, поскольку, исходя из моего наивного понимания, транзакция, похоже, выполняется на docRef.

Пока что у меня есть код, аналогичный приведенному ниже, после этого SO thread , но я думаю, что это будет работать только для первого элемента, а не для второго? Другими словами, если do c обновляется другим пользователем процессора, он будет запущен повторно, но ничего не сделает, т.е. выберет следующих 2 основных пользователей, которые все еще не обработаны? Есть ли способ добиться этого? Я понимаю, что мне может понадобиться какой-то l oop здесь?

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

var entriesRef = db.collection('entries');
var snapshot = entriesRef.where("status", "=", 'PENDING').orderBy("createTime").limit(2);
var docRefs = [];
snapshot.forEach(doc => {
  console.log(doc.id, '=>', doc.data());
  docRefs.push(entriesRef.doc(doc.id));
});

let promise = await admin.firestore().runTransaction(transaction => {
  var post = transaction.get(docRefs[0]);
  var anotherPost = transaction.get(docRefs[1]);

  if (post.status === 'PENDING' && anotherPost.status === 'PENDING') {
    var newStatus = 'BEING PROCESSED'
    await transaction.update(docRef[0], { status: newStatus });
    await transaction.update(docRef[1], { status: newStatus });
  }
});

1 Ответ

0 голосов
/ 03 августа 2020

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

Все документы, которые вы get() и update() используете объект транзакции, будут обрабатываться атомарно. В этом весь смысл сделки. Если какой-либо из документов, которые вы get() изменяет какой-либо другой клиент во время транзакции, функция обработчика транзакции будет повторена. Ваш код должен быть подготовлен для этого.

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

...