如何缓存doPost请求以避免短时间多次请求写入Google Sheet时数据覆盖?
解决Google Sheet并发写入覆盖问题的可用方案
- 方案1:使用Google Apps Script原生的
LockService并发锁
这是最直接适配现有代码的方案,锁会保证同一时间只有一个请求执行写入逻辑,其他请求等待锁释放后再执行,避免多个请求同时拿到相同的最后行号。
修改后的代码示例:
function doPost(e){ // 获取脚本级全局锁,设置最长等待时间30秒,可根据实际请求量调整 const lock = LockService.getScriptLock(); try { lock.waitLock(30000); var data = e.postData.contents; var output = parser(data); writePayload(output); return ContentService.createTextOutput('ok'); } catch (err) { // 等待超时返回请求频率过高错误,可根据业务需要自定义处理逻辑 return ContentService.createTextOutput('too many requests').setResponseCode(429); } finally { // 执行完成后强制释放锁,避免死锁 lock.releaseLock(); } }
- 方案2:替换写入逻辑为原子操作
appendRow
你当前的writePayload逻辑是先查最后一行再写入,本身就存在竞态条件。Google Sheet提供的appendRow方法是官方实现的原子操作,写入时会自动定位到当前真实的最后一行的下一行,不会出现多个请求写入同一行的问题,单条数据写入场景下可以直接替换原有写入逻辑:
// 优化后的writePayload示例 function writePayload(flatData) { const targetSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('你的表格名'); // flatData是一维数组,对应一行的多列内容 targetSheet.appendRow(flatData); }
如果需要一次性写入多行数据,可以把方案1和方案2结合,加锁之后再批量写入即可。
- 方案3:用缓存做批量队列写入(适合高请求量场景)
如果每秒请求数超过10次,可以用CacheService把接收到的payload先缓存到队列中,搭配时间驱动触发器,每1-5分钟批量写入一次表格,这种方式可以大幅降低表格的写入频率,避免锁等待超时问题,但实现复杂度更高,普通低并发场景不需要用到。
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

