У меня есть следующая структура:
{
"point_logs": {
"user1": {
"LrDm-0OBBg84rTSXGyF": {
"action": "action_type_1",
"point": 1
},
"LrDm0b0oF-48EF3ZsqF": {
"action": "action_type_2",
"point": 1
}
},
"user2": {
"LrDm0dfZsEE40HvnwEc": {
"action": "action_type_5",
"point": 1
},
"LrDm0gKsdEw3O3ync_7": {
"action": "redeem_1",
"point": -2
}
}
}
}
В настоящее время я добавляю облачную функцию firebase, чтобы выкупить точку, поскольку облачная функция - async
, чтобы убедиться, что есть достаточно точек для выкупа. Мне нужно сделать функцию выкупа атомной.
Я пытался использовать транзакцию:
exports.redeemPoints = functions.https.onRequest((req, res) => {
db.ref('/point_logs/' + user_id).transaction((data) => {
admin.database().ref('/points_assign_logs/' + user_id).once('value', (snapshot) => {
// code to iterate and sum all points from this user's logs
if (remain_points >= redeem_point) {
admin.database().ref('/point_logs/' + user_id).push(redeem_log);
}
return data
});
});
});
Но при многократном асинхронном вызове этой функции оставшаяся точка может быть отрицательной, даже если есть проверка if (remain_points >= redeem_point)
.
Как правильно выполнить транзакцию пользователя для атомарного обновления этого журнала?