You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Firebase Realtime Database中实现Sequence/计数器结构并解决并发问题

static Future<int> get nextId async {
  return database.get().then((snapshot) {
    return snapshot.value;
  }).then((value) {
    database.set(value + 1);
    return value + 1;
  });
}
结论

你当前的实现逻辑在多用户并发调用时,必然存在获取到相同返回值的风险。

风险产生的原因
  • 这段逻辑属于非原子的「读-改-写」操作序列,读取、修改、写入是三个完全独立的步骤,且步骤之间没有任何并发安全保障
  • 并发场景下会出现如下异常时序:
    1. 用户1调用nextId,首先通过database.get()读取到当前值为10
    2. 还没等用户1执行database.set(11)操作,用户2也调用了nextId,同样读取到当前值为10
    3. 两个用户后续都会执行写入11的操作,且最终都返回11,出现ID重复
修复方案

你需要避免自行拆分读、写操作,优先使用你所用NoSQL数据库原生提供的原子自增操作,这类操作由数据库底层保证原子性,并发场景下不会出现重复:

  • 如果你使用的是Firebase系列数据库,可直接使用ServerValue.increment(1)完成原子自增
  • 如果你使用的是MongoDB,可使用$inc操作符完成原子增减
  • 如果你使用的是Redis,可直接调用INCR命令完成自增
    如果你的NoSQL数据库确实没有提供原生原子自增能力,你需要额外引入分布式锁,在读取ID前先加锁,完成写入操作后再释放锁,避免多个请求同时读写同一个序列值。

内容的提问来源于stack exchange,提问作者Vetrivelu Murugesan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 17:36:04