考虑以下:
function useCredits(userId, amount){
var userRef = firebase.database().ref().child('users').child(userId);
userRef.transaction(function(user) {
if (!user){
return user;
}
user.credits -= amount;
return user;
}, NOOP, false);
}
function notifyUser(userId, message){
var notificationId = Math.random();
var userNotificationRef = firebase.database().ref().child('users').child(userId).child('notifications').child(notificationId);
userNotificationRef.transaction(function(notification) {
return message;
}, NOOP, false);
}
这些是从同一个节点 js 进程调用的。
一个用户看起来像这样:
{
"name": 'Alex',
"age": 22,
"credits": 100,
"notifications": {
"1": "notification 1",
"2": "notification 2"
}
}
当我运行压力测试时,我注意到有时传递给 userRef 事务更新函数的用户对象不是完整用户,它只是以下内容:
{
"notifications": {
"1": "notification 1",
"2": "notification 2"
}
}
这显然会导致错误,因为 user.credits 不存在。
可疑的是传递给 userRef 事务的更新函数的用户对象与 userNotificationRef 事务的更新函数返回的数据相同。
为什么会这样?如果我在用户父位置上运行两个事务,这个问题就会消失,但这是一个不太理想的解决方案,因为我会有效地锁定并读取整个用户对象,这在添加一次写入通知时是多余的。