高负载谷歌表格中appendRow()不可靠覆盖已有数据问题咨询
问题原因
这个问题不是平台bug,是高负载表格下的并发写入竞争导致的。你推测的逻辑是正确的:高负载表格因为有大量公式和条件格式,写入数据后表格元数据(最后一行序号)的更新延迟远高于轻量表格。如果短时间内多个submitUpload请求并发执行,后一个请求调用appendRow时,前一个请求的写入还没完成表格状态同步,拿到的还是旧的最后一行序号,就会把数据写到和前一个请求相同的行,导致覆盖。轻量表格状态更新快,请求间隔足够完成同步,所以不会出现该问题。
解决方案
最直接的修复方式是在服务端加锁,强制写入请求排队执行,避免并发竞争,修改后的code.gs代码如下:
function doGet(e) { return HtmlService.createHtmlOutputFromFile('UPLOAD'); } function submitUpload(shotid){ // 获取脚本级锁,拦截并发写入请求 const lock = LockService.getScriptLock(); try { // 最长等待锁30秒,可根据实际场景调整 lock.waitLock(30000); Logger.log(shotid); const ssid = "1EgFPSz2IoJDc1HfU9G2iX_PmwXMgBvY-M8YcsQfsTMQ"; const SS = SpreadsheetApp.openById(ssid); const Usheet = SS.getSheetByName("UPLOADSTACK"); Usheet.appendRow([shotid]); // 强制同步写入结果,确保后续请求拿到最新的表格状态 SpreadsheetApp.flush(); } catch (err) { console.error('写入失败', err); throw new Error('写入超时,请稍后重试'); } finally { // 操作完成后释放锁,给后续请求使用 lock.releaseLock(); } }
可选优化
如果你的业务允许,还可以再加两层优化进一步降低出错概率:
- 前端增加全局提交状态限制,同一时间只允许一个提交请求执行,避免短时间内大量请求排队导致超时
- 新增一个无公式、无格式的轻量中转表,所有写入请求先写到中转表,再用定时触发器定期把中转表的数据同步到高负载的主表,进一步降低写入延迟
内容的提问来源于stack exchange,提问作者andio
相关产品推荐
相关产品推荐

