Firebase транзакции

Поддержка транзакций является одной из основных причин выбрать реляционную базу даных вместо NoSQl. В особенности если для вашего приложение очень важна точность и корректность даных. Firebase хотя и не поддерживает ACID, дает возможность атомарного изменения даных. В этой статье рассмотрим механизм транзакций firebase realtime database.

Транзакционное обновление даных

Если вы работаете с данными которые могут перезаписанными некорректным или устаревшим значением и/или несколькими клиентами нужно использовать firebase транзакции
Сигнатура метода выглядит так

ref.transaction(transactionUpdate:function, onComplete:function, applyLocally:boolean) returns firebase.Promise with data {committed: boolean, snapshot: nullable firebase.database.DataSnapshot}

Метод firebase.database.Reference.transaction атомарно изменяет данные в заданном узле.
В отличие от метода set(), который полностью перезаписывает данные не смотря,на то что там было записано раньше, метод transaction() нужно использовать чтобы изменить существующее значение на новое значение, гарантировано согласованное с изменениями других клиентов, которые пытаются записать данные в тот же момент.

Что бы реализовать это, нужно передать в метод transaction(), функцию которая базируясь на текущем значение обновит новое значение. Если другой клиент обновляет узел до того, как ваше новое значение было записано, ваша update функция будет вызвана еще раз, уже с новым текущим значением и будет сделана новая попытка сохранить значения. Это будет повторятся до тех пор, пока ваша транзакции не закончится успешно или вы не выйдете с транзакции вернув undefined как результат.

Стоить заметить что вызов метода set() отменит все активные транзакции в обновленном узле, поэтому нужно избегать совместного использование методов transaction() и set() для обновление данных в определённом пути.

Также для выполнения транзакции клиенту необходимо иметь доступ .read и .write. Правила доступа задаются в консоли.

Параметры метода transaction()
transactionUpdate – функция которая предоставляется разработчиком, как параметр она принимает текущее значение. Функция должна вернуть обновленное значение. Как говорилось ранее если вернуть undefined, транзакция будет остановлена и данные не будут изменены.
onComplete – необязательный параметр функция

 function(nullable Error, boolean, nullable firebase.database.DataSnapshot)

Это функция колбек которая будет вызвана после завершения транзакции. Функции принимает три параметра, первый – ошибка, если транзакция завершилась аварийно, второй – болевое значении, true если данные били записаны в базу, false если нет. Последние значение, которое было записано

applyLocally – по умолчанию события вызываются каждый раз, когда выполняется update функция. И если она выполняется несколько раз вы будете видеть промежуточные состояния, пока транзакция не завершится onComplete.

Метод transaction() возвращает Promise , его можно использовать как аналог функции onComplete

Пример использование firebase транзакций
let commentsLikeRef = firebase.database().ref('comments/uid/');
commentsLikeRef.transaction(function(likeCount) {
 if (likeCount == null)
  likeCount == 0;

 return ++likeCount;
}, function(error, committed, snapshot) {
 if (error) {
  console.log('Transaction failed abnormally!', error);
 }
 console.log('committed:', committed);

}, false).then(function(data) {
 return resolve({
  likeCount: snapshot.val()
 })
});
Одновременное обновление нескольких узлов

На данный момент Firebase не поддерживает атомарное обновление нескольких узлов.

Заключение

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

 

nazarmsx

 

Leave a Reply

Your email address will not be published. Required fields are marked *