首页 > 解决方案 > 我是否正确使用了 Google Apps 脚本锁定服务?

问题描述

我在一个脚本中有 3 个 Apps 脚本函数。该脚本部署为公共访问 Web 应用程序。

每个函数都从它自己的谷歌表中读取。每个函数都不向工作表写入任何内容。

我已将 Apps 脚本“LockService”应用于每个函数,以防止多个用户同时通过 webapp 访问电子表格。实际上使每个用户等到前一个用户的脚本完成阅读。他们可以阅读 3 张纸。

我发现这有时会在应用程序更新之前为用户造成 4 或 5 秒的延迟——这非常令人反感。

那么我的问题是我应该 - a)打扰 LockService,因为我只是在读取电子表格数据,也许 LockService 的主要目的是防止并发读取和写入之间的冲突

或者

b)我是否正确实施它,因为同时读取数据也可能导致冲突,例如获取范围值等。

谢谢

编辑:如果选项'a'那么我想知道 LockService 的目的是什么?当您使用多个“google.script.run”时,可能是一个原因(就像我在其他脚本中的其他地方一样)。一个接一个地通过不同的函数访问同一个电子表格,然后 - 由于这些函数是异步运行的 - 如果两个请求都试图获取数据,则可能会产生冲突。

只是在想真的....

标签: google-apps-scriptweb-applications

解决方案


LockService如果您所做的只是读取数据,则无需使用。因此,选项(a)。

无需保护 Apps Script 或 Google Sheets 免受并发,即使是来自同一用户的写入操作。您从 Apps 脚本执行的每个并行访问都完全独立于彼此运行,它是您的应用程序的一个新实例,不与其他人共享任何内容,它甚至可能完全在不同的服务器上运行。Google 表格可以很好地处理并发,并发协作是 G Suite 应用程序的重点。

那么,你什么时候需要LockService

当您的应用程序逻辑需要这样时。例如,为了保护自己不弄乱自己的数据。假设您想计算点击次数并将该数字保存在工作表上,例如Sheet1!B2. 所以你的代码看起来像:

function countClicks() {
  var r = SpreadsheetApp.getActive().getSheetByName('Sheet1').getRange('B2');
  var clicks = r.getValue();
  clicks = clicks + 1;
  r.setValue(clicks);
}

如果这个函数同时运行,你不会破坏你的记忆或破坏谷歌表格,所有这一切都会发生,你可能会覆盖自己,就好像你有多个用户试图在同一个单元格中输入:最后一个获胜。

但是你的逻辑会被打破,即多个并发点击可能被算作一次。那是LockService进来的时候,以保护您的逻辑:

function countClicks() {
  var r = SpreadsheetApp.getActive().getSheetByName('Sheet1').getRange('B2');
  var lock = LockService.getDocumentLock();
  lock.waitLock(10000); //throws exception if fails to acquire lock
  //you could try-catch it, but that's irrelevant in this example
  r.setValue(r.getValue()+1);
  SpreadsheetApp.flush(); //forces the script to actually send the values to Sheets
  lock.releaseLock();
}

希望这可以澄清它。

顺便说一句,这只是一个非常蹩脚的例子。这不是您应该计算点击次数的方式,因为正如您所指出的,锁定会在您的系统中增加显着的延迟。因此,您应该寻找替代方案,可能按用户拆分数据或使用appendRow 之类的原子操作。


推荐阅读