Class Lock

锁定

互斥锁的表示法。

借助此类,脚本可以确保一次只有一个脚本实例执行给定代码段。这对于回调和触发器特别有用,因为在这些情况下,用户操作可能会导致共享资源发生变化,而您希望确保不会发生冲突。

以下示例展示了如何在表单提交处理脚本中使用锁。

// Generates a unique ticket number for every form submission.
function onFormSubmit(e) {
  const targetCell = e.range.offset(0, e.range.getNumColumns(), 1, 1);

  // Gets a script lock before modifying a shared resource.
  const lock = LockService.getScriptLock();
  // Waits for up to 30 seconds for other processes to finish.
  lock.waitLock(30000);

  const scriptProperties = PropertiesService.getScriptProperties();

  const ticketNumber =
      Number(scriptProperties.getProperty('lastTicketNumber')) + 1;
  scriptProperties.setProperty('lastTicketNumber', ticketNumber);

  // Releases the lock so that other processes can continue.
  lock.releaseLock();

  targetCell.setValue(ticketNumber);
}
如果没有 Lock 服务,如果两位用户大致同时提交表单,则工单编号可能会相同,因为 lastTicketNumber 属性可能会在从 ScriptProperties 读取后,但在新值写回之前发生变化。

方法

方法返回类型简介
hasLock()Boolean如果已获取锁,则返回 true。
releaseLock()void释放锁,允许等待锁的其他进程继续运行。
tryLock(timeoutInMillis)Boolean尝试获取锁,并在提供的毫秒数后超时。
waitLock(timeoutInMillis)void尝试获取锁,并会在提供的毫秒数过后超时并抛出异常。

详细文档

hasLock()

如果已获取锁,则返回 true。如果从未调用 tryLock(timeoutInMillis)waitLock(timeoutInMillis)、在检索锁之前超时,或者调用了 releaseLock(),此方法将返回 false。

const lock = LockService.getScriptLock();
lock.tryLock(10000);
if (!lock.hasLock()) {
  Logger.log('Could not obtain lock after 10 seconds.');
}

返回

Boolean - 如果已获取锁,则为 true,否则为 false


releaseLock()

释放锁,允许等待锁的其他进程继续运行。脚本终止时,锁会自动释放,但为了提高效率,最好在不再需要对某段代码的独占访问权限时立即释放该锁。如果尚未获取锁,此方法将无效。

请注意,如果您正在处理电子表格,则应在释放锁定之前调用 SpreadsheetApp.flush(),以便在您仍拥有对该电子表格的独占访问权限时将所有待处理的更改提交到该电子表格。

const lock = LockService.getScriptLock();
lock.waitLock(10000);
// Do some work on a shared resource.
lock.releaseLock();

tryLock(timeoutInMillis)

尝试获取锁,并在提供的毫秒数后超时。如果已获取锁,此方法将无效。

const lock = LockService.getScriptLock();
const success = lock.tryLock(10000);
if (!success) {
  Logger.log('Could not obtain lock after 10 seconds.');
}

参数

名称类型说明
timeoutInMillisInteger获取锁的等待时间(以毫秒为单位)

返回

Boolean - 如果已获取锁,则为 true,否则为 false


waitLock(timeoutInMillis)

尝试获取锁,并会在提供的毫秒数过后超时并抛出异常。此方法与 tryLock(timeoutInMillis) 相同,只是在无法获取锁定时会抛出异常,而不是返回 false。

const lock = LockService.getScriptLock();
try {
  lock.waitLock(10000);
} catch (e) {
  Logger.log('Could not obtain lock after 10 seconds.');
}

参数

名称类型说明
timeoutInMillisInteger获取锁的等待时间(以毫秒为单位)

抛出

Error - 如果方法在获取锁之前超时