我是否正确使用了Google Apps脚本锁定服务?

时间:2019-03-07 18:36:43

标签: google-apps-script web-applications

我在一个脚本中有3个Apps脚本功能。该脚本被部署为公共访问Web应用。

每个函数都从其自己的Google工作表中读取。每个函数都不会在工作表中写入任何内容。

我已将Apps脚本“ LockService”应用于每个功能,以防止多个用户同时通过Web应用程序访问电子表格。实际上,使每个用户都等到前一个用户的脚本读完为止。他们阅读了三张纸。

我发现在更新应用程序之前,这有时会给用户造成4到5秒钟的延迟-这是不可行的。

那么我的问题是我应该- a)麻烦LockService,因为我只是在读取电子表格数据,而LockService的主要目的可能是防止并发读写之间的冲突

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

谢谢

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

真的很想念...。

1 个答案:

答案 0 :(得分:0)

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

无需保护Apps脚本或Google表格的并发性,甚至不必由同一用户执行写操作。您通过Apps脚本执行的每次并行访问都完全独立于彼此运行,它是您的应用程序的新实例,不与他人共享任何内容,甚至可能完全在其他服务器上运行。 Google Sheets可以很好地处理并发性,并发协作是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);
}

如果此函数同时运行,则不会破坏内存或使Google表格中断,所有要做的就是您可能会覆盖自己,就像您有多个用户试图在同一单元格中键入内容一样:最后一个获胜。

但是您的逻辑将被破坏,也就是说,多个并发点击可能被视为一次点击。那是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();
}

希望这可以澄清它。

顺便说一下,这只是一个非常la脚的例子。这不是您应该计算点击次数的方式,因为您已经指出,锁定会增加系统的延迟。因此,您应该寻找替代方法,例如按用户拆分数据或使用appendRow之类的原子操作。