Хотелось бы узнать, можно ли использовать нестандартную транзакцию вместо стандартной. Есть ли проблема повреждения данных при использовании второго метода?
Если, например, мой счетчик равен 0, и два человека одновременно увеличивают его до 1. Счетчик поврежден или запрос помещен в очередь и выполняется позже?
правила
".write": "data.val() == null && newData.val() == 1 || newData.val() == data.val() + 1"
стандартная транзакция
const db = firebaseApp.database();
const ref = db.ref().child('node/counter');
ref.transaction(count => {
if (count === null) {
return count = 1
} else {
return count + 1
}
});
настраиваемая транзакция
const customTransaction = async (retry = 10) => {
const db = firebaseApp.database();
const ref = db.ref().child('node/counter');
for (let i = 0; i < retry; i++) {
try {
const snapshot = await ref.once('value');
const counter = snapshot.val() ? snapshot.val() : 0;
await ref.set(counter + 1);
return counter + 1;
} catch (e) {
if(i >= retry - 1) {
throw new Error(e);
}
}
}
}
try {
await customTransaction(20);
} catch (e) {
console.log(e);
}
настраиваемая с несколькими счетчиками
const customTransaction = async (retry = 10) => {
const db = firebaseApp.database();
const ref = db.ref().child('node/');
for (let i = 0; i < retry; i++) {
try {
const snap = await ref.child('counter').once('value');
const snap1 = await ref.child('counter1').once('value');
const snap2 = await ref.child('counter2').once('value');
const counter = snap.val() ? snap.val() : 0;
const counter1 = snap1.val() ? snap1.val() : 0;
const counter2 = snap2.val() ? snap2.val() : 0;
const paths = {};
paths['node/counter'] = counter + 1;
paths['node/counter1'] = counter1 + 1;
paths['node/counter2'] = counter2 + 1;
await db.ref().update(paths);
return {
counter: counter + 1,
counter1: counter1 + 1,
counter2: counter2 + 1
}
} catch (e) {
if(i >= retry - 1) {
throw new Error(e);
}
}
}
}
try {
await customTransaction(20);
} catch (e) {
console.log(e);
}