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如果取得鎖定,則傳回「是」。
releaseLock()void釋出鎖定,讓等待鎖定的其他程序繼續執行。
tryLock(timeoutInMillis)Boolean嘗試取得鎖定,在提供的毫秒數過後逾時。
waitLock(timeoutInMillis)void嘗試取得鎖定,在提供的毫秒數過後逾時並產生例外狀況。

內容詳盡的說明文件

hasLock()

如果取得鎖定,則傳回「是」。如果從未呼叫 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:如果方法在取得鎖定前逾時