使用Lock Service实现Google Apps Script Webhook同步执行解决数据覆盖问题
现有代码问题
- 空catch块导致锁机制失效:
lock.waitLock(30000)超时抛出异常后,代码仍会继续执行写入逻辑,锁完全没有起到隔离并发的作用 - 锁释放逻辑存在隐患:如果写入表格阶段抛出异常,
lock.releaseLock()不会执行,锁会一直占用到自动过期,导致后续请求大面积超时 - 多余的
Utilities.sleep(20000)无实际意义,还大幅拉长了单次请求的执行时间,大幅提升锁超时概率
修正后代码
function doGet(e) { // 获取脚本全局共享锁 const lock = LockService.getScriptLock(); try { // 最多等待30秒获取锁,拿不到直接抛出异常 lock.waitLock(30000); // 执行业务写入逻辑 const targetSheet = SpreadsheetApp.openByUrl("SHEET_URL").getSheets()[0]; targetSheet.appendRow([e.parameter.script]); // 确保写入操作完全落地再释放锁 SpreadsheetApp.flush(); // 自定义正常返回内容 return ContentService.createTextOutput("success").setMimeType(ContentService.MimeType.TEXT); } catch (error) { // 拿锁失败或执行异常时返回错误,调用方可根据返回做重试 return ContentService.createTextOutput("failed").setMimeType(ContentService.MimeType.TEXT); } finally { // 无论执行成功还是失败,只要当前持有锁就执行释放,避免锁死 if (lock.hasLock()) { lock.releaseLock(); } } }
核心优化说明
- 补全了异常处理逻辑:获取锁失败时直接返回错误,不会再执行写入操作,从根源避免并发写入冲突
- 锁释放移入
finally块:就算写入过程中出现报错,也会正常释放锁,不会影响后续请求执行 - 新增锁持有校验:仅当前实例真的持有锁时才执行释放操作,避免不必要的报错
- 删除无用的20秒等待逻辑:大幅降低单次请求执行时长,减少锁超时的概率
- 补充标准返回值:Webhook调用方可以明确判断请求结果,方便做失败重试逻辑
内容的提问来源于stack exchange,提问作者Code Guy
相关产品推荐
相关产品推荐

