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

App Script场景下Slides API批量更新的队列并发冲突如何解决?

解决方案

方案1:使用内置LockService处理并发(优先推荐)

Apps Script提供了原生的LockService服务,专门用于解决多实例并发执行的资源冲突问题,你可以将「读取队列号→更新队列号→调用Slides API」的整个临界区逻辑加入排他锁,保证同一时间只有一个脚本实例执行这段代码,从根源避免队列号重复:

// 获取排他锁,最长等待30秒
const lock = LockService.getScriptLock();
try {
  lock.waitLock(30000);
  // 原有的队列读写逻辑
  var array = sessionsSheets.getRange(row, 2, 1, 3).getValues()[0];
  var questionNumber = array[2];
  // 建议把setFormula改成setValue直接写入固定值,避免公式二次计算带来的意外问题
  sessionsSheets.getRange(`D${row}`).setValue(questionNumber + 1);
  // 调用Slides API
  Slides.Presentations.batchUpdate({'requests': requests}, presentationId);
} catch (e) {
  // 可在这里添加错误日志记录逻辑
  throw e;
} finally {
  // 执行完务必释放锁,避免其他实例等待超时
  lock.releaseLock();
}

方案2:同步重试机制

如果你不需要严格控制执行顺序,也可以用同步重试逻辑实现冲突重试,不需要Promise支持:

const MAX_RETRY = 5; // 最大重试次数,避免死循环
let retryCount = 0;
let success = false;

while (!success && retryCount < MAX_RETRY) {
  try {
    // 每次重试都重新读取最新的队列号
    var array = sessionsSheets.getRange(row, 2, 1, 3).getValues()[0];
    var questionNumber = array[2];
    sessionsSheets.getRange(`D${row}`).setValue(questionNumber + 1);
    Slides.Presentations.batchUpdate({'requests': requests}, presentationId);
    success = true;
  } catch (e) {
    // 判断是否是队列号重复导致的错误,只有该类错误才重试,替换成实际报错的特征内容即可
    if (e.message.includes('队列号重复相关的错误特征字符串')) {
      retryCount++;
      Utilities.sleep(100 * retryCount); // 指数退避等待,降低再次冲突的概率
    } else {
      // 非重复类错误直接抛出
      throw e;
    }
  }
}

if (!success) {
  throw new Error('重试次数已达上限,队列号冲突仍未解决');
}

额外优化建议

  • 队列号的更新尽量用setValue写入固定数值,避免setFormula引入的公式计算延迟、多实例同时触发公式计算的额外冲突问题
  • 如果队列号使用频率很高,也可以将队列号存储在PropertiesService中,读写速度比电子表格更快,锁冲突概率更低

内容的提问来源于stack exchange,提问作者Mike Harb

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 17:33:00