Firebase Realtime Database多用户并发更新时onUpdate触发器执行顺序咨询
函数并发执行逻辑
Firebase Realtime Database的onUpdate触发器默认不会严格按更新顺序排队串行执行,高并发场景下多个更新请求会触发多个函数实例并行运行,完全可能出现两个更新触发的函数同时执行的情况。
现有代码的潜在问题
- 首先代码存在笔误:你计算出的差值存在
diff变量中,但更新totalDivi时用的是未定义的divi变量,实际运行会直接报错,需要先修正。 - 核心逻辑风险:你当前使用的是「先读totalDivi的值 -> 计算新值 -> 写入新值」的读改写流程,没有做并发控制,高并发下会出现数据丢失。比如当前
totalDivi为100,用户A更新tokenEarned产生差值10,用户B同时更新产生差值20,两个函数同时读到totalDivi=100,A计算得到110写入,B计算得到120写入,最终totalDivi的值为120,而非正确的130,少累加了A的差值。
正确实现方案
不需要依赖函数执行顺序保证数据正确性,直接用Realtime Database自带的transaction方法处理累加即可,它会自动处理并发冲突,遇到写入冲突时自动重试读改写流程,保证最终数据正确,修改后的参考代码如下:
exports.XXX = functions.database.ref("/global/tokenEarned") .onUpdate(async (change, context) => { const newValue = change.after.val(); const oldValue = change.before.val() if(oldValue !== newValue){ const diff = newValue - oldValue // 用transaction更新totalDivi,避免并发冲突 await db.ref("global/totalDivi").transaction(current => { return (current || 0) + diff }) } return null })
如果业务上必须严格保证函数按更新顺序执行,你可以给该云函数配置最大实例数为1,同时开启事件排序,但该方案会降低高并发下的处理吞吐量,绝大多数场景下用transaction已经足够。
内容的提问来源于stack exchange,提问作者Moblize IT
相关产品推荐
相关产品推荐

