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

多用户调用云函数是否会冲突?Firestore生命值读写冲突及解决

问题解答

竞态条件确实会发生

你描述的这种情况是典型的竞态条件,完全可能出现。当多个用户同时调用InflictDamageToEnemy云函数时:

  • 多个函数实例会几乎同时读取敌人当前的生命值
  • 其中一个实例先完成计算并写入新生命值
  • 后续实例基于之前读取的旧生命值计算,写入的结果会忽略掉前面实例造成的伤害,相当于部分攻击无效

举个实际例子:敌人初始生命值100,两个玩家的攻击都是30。如果两个函数实例同时读取到100,各自计算后写入70,最终敌人生命值会是70,而不是正确的40——相当于其中一次攻击被“吞”了。

解决方案:使用Firestore事务

必须用Firestore的事务来处理这种依赖当前数据状态的读写操作,这正是事务的核心应用场景。

事务能确保:

  1. 整个读写操作是原子性的——要么全部执行成功,要么全部失败,不会出现中间状态
  2. 在事务执行期间,Firestore会自动检测目标文档是否被修改,一旦发现冲突就重试事务,直到成功或达到重试上限

改造后的云函数示例(JavaScript)

const functions = require("firebase-functions");
const admin = require("firebase-admin");
admin.initializeApp();
const db = admin.firestore();

exports.inflictDamageToEnemy = functions.https.onCall(async (data, context) => {
  // 敌人文档引用(可根据实际业务从参数获取或固定)
  const enemyDocRef = db.collection("enemies").doc("target_enemy");
  // 当前调用玩家的文档引用
  const playerDocRef = db.collection("players").doc(context.auth.uid);

  return db.runTransaction(async (transaction) => {
    // 1. 在事务中读取玩家攻击力和敌人当前生命值
    const playerSnapshot = await transaction.get(playerDocRef);
    const enemySnapshot = await transaction.get(enemyDocRef);

    if (!playerSnapshot.exists || !enemySnapshot.exists) {
      throw new functions.https.HttpsError("not-found", "玩家或敌人数据不存在");
    }

    const playerAttack = playerSnapshot.data().attack;
    let currentEnemyHealth = enemySnapshot.data().health;

    // 2. 计算新生命值(确保不低于0)
    currentEnemyHealth -= playerAttack;
    currentEnemyHealth = Math.max(currentEnemyHealth, 0);

    // 3. 在事务中更新敌人生命值
    transaction.update(enemyDocRef, { health: currentEnemyHealth });

    return { newEnemyHealth: currentEnemyHealth };
  }).catch((err) => {
    functions.logger.error("事务执行失败:", err);
    throw new functions.https.HttpsError("aborted", "攻击操作失败,请稍后重试");
  });
});

为什么事务能解决问题?

  • 事务中的所有操作会被Firestore作为一个整体处理,不会被其他操作打断
  • 如果在事务读取文档后,其他操作修改了该文档,Firestore会自动重试整个事务流程,确保每次计算都是基于最新的生命值数据
  • 不需要手动处理锁机制,Firestore会自动处理冲突和重试逻辑

内容的提问来源于stack exchange,提问作者Average Joe

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 01:05:17