синхронизация доступа к базе данных Firebase - PullRequest
0 голосов
/ 22 октября 2018

У меня есть один экземпляр базы данных Firebase, и я хотел бы добавить счетчик для определенного узла.

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

Пример.

database{
node {
counter : 0
}

}

В определенное время 3 разных пользователя читают значение на счетчике и пытаются увеличить его.Поскольку они читают в одно и то же время, все они читают «0» и увеличивают до «1», но желаемое значение в конце выполнения должно быть «3», поскольку оно было прочитано 3 раза

================== update ===================

@ renaud указывает на использование транзакций для сохранения синхронизации наиз сохраненных данных, но у меня есть другой сценарий, где мне нужно сделать синхронизацию на стороне чтения также:

ex.пользователь читает фактическое значение, в соответствии с ним выполняет другое действие и завершает, увеличивая на единицу ...

в среде, подобной SQL, я бы написал процедуру для этого, потому что не имеет значения, какой пользователь будетс информацией, которую я всегда буду заканчивать, увеличивая на единицу

Если я правильно понял ответ @renaud, в этом сценарии 4 разных пользователя, читающих базу данных одновременно, получат 0 в качестве текущего значения, а затем при обновлении транзакцииКонечное сохраненное значение будет 4, но на стороне клиента каждый из них просто читает 0

1 Ответ

0 голосов
/ 22 октября 2018

Вы должны использовать Транзакцию в этом случае, см. https://firebase.google.com/docs/database/web/read-and-write#save_data_as_transactions, а также https://firebase.google.com/docs/reference/js/firebase.database.Reference#transaction

Транзакция "обеспечит отсутствие конфликтов с другими клиентами, пишущими в то же место вв то же время. "

В облачной функции вы можете написать свой код в следующих строках, например:

....
const counterRef = admin
  .database()
  .ref('/node/counter');

return counterRef
  .transaction(current_value => {
    return (current_value || 0) + 1;
  })
  .then(counterValue => {
    if (counterValue.committed) {
      //For example update another node in the database 
      const updates = {};
      updates['/nbrOfActionsExecuted'] = counterValue.snapshot.val();
      return admin
        .database()
        .ref()
        .update(updates);
    }
  })

или просто следующее, если вы просто хотите обновить счетчик (так кактранзакция возвращает обещание, как описано во второй ссылке, указанной выше):

exports.testTransaction = functions.database.ref('/path').onWrite((change, context) => {
  const counterRef = admin
    .database()
    .ref('/node/counter');

  return counterRef
    .transaction(current_value => {
      return (current_value || 0) + 1;
    });
});

Обратите внимание, что во втором случае я использовал триггер базы данных реального времени в качестве примера триггера.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...