Stay organized with collectionsSave and categorize content based on your preferences.
Lock
A representation of a mutual-exclusion lock.
This class lets scripts make sure that only one instance of the script executes a given
section of code at a time. This is particularly useful for callbacks and triggers, where a user
action might cause changes to a shared resource and you want to ensure that there aren't
collisions.
The following example shows how to use a lock in a form submit handler.
// Generates a unique ticket number for every form submission.functiononFormSubmit(e){consttargetCell=e.range.offset(0,e.range.getNumColumns(),1,1);// Gets a script lock before modifying a shared resource.constlock=LockService.getScriptLock();// Waits for up to 30 seconds for other processes to finish.lock.waitLock(30000);constscriptProperties=PropertiesService.getScriptProperties();constticketNumber=Number(scriptProperties.getProperty('lastTicketNumber'))+1;scriptProperties.setProperty('lastTicketNumber',ticketNumber);// Releases the lock so that other processes can continue.lock.releaseLock();targetCell.setValue(ticketNumber);}
Without the Lock service, if two users submit the form at approximately the same time, the ticket
numbers could end up the same, since thelastTicketNumberproperty could change after it
was read from theScriptPropertiesbut before the new value was written back.
constlock=LockService.getScriptLock();lock.tryLock(10000);if(!lock.hasLock()){Logger.log('Could not obtain lock after 10 seconds.');}
Return
Boolean— true if the lock was acquired, false otherwise
releaseLock()
Releases the lock, allowing other processes waiting on the lock to continue. The lock is
automatically released when the script terminates, but for efficiency it is best to release it
as soon as you no longer need exclusive access to a section of code. This method has no effect
if the lock has not been acquired.
Note that if you are working with a spreadsheet, you should call SpreadsheetApp.flush()
prior to releasing the lock, to commit all pending changes to the spreadsheet while you still
have exclusive access to it.
constlock=LockService.getScriptLock();lock.waitLock(10000);// Do some work on a shared resource.lock.releaseLock();
tryLock(timeoutInMillis)
Attempts to acquire the lock, timing out after the provided number of milliseconds. This method
has no effect if the lock has already been acquired.
constlock=LockService.getScriptLock();constsuccess=lock.tryLock(10000);if(!success){Logger.log('Could not obtain lock after 10 seconds.');}
Parameters
Name
Type
Description
timeoutInMillis
Integer
how long to wait to acquire the lock, in milliseconds
Return
Boolean— true if the lock was acquired, false otherwise
waitLock(timeoutInMillis)
Attempts to acquire the lock, timing out with an exception after the provided number of
milliseconds. This method is the same astryLock(timeoutInMillis)except that it throws an exception
when the lock could not be acquired instead of returning false.
constlock=LockService.getScriptLock();try{lock.waitLock(10000);}catch(e){Logger.log('Could not obtain lock after 10 seconds.');}
Parameters
Name
Type
Description
timeoutInMillis
Integer
how long to wait to acquire the lock, in milliseconds
Throws
Error— if the method timed out before the lock was acquired
[[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Missing the information I need","missingTheInformationINeed","thumb-down"],["Too complicated / too many steps","tooComplicatedTooManySteps","thumb-down"],["Out of date","outOfDate","thumb-down"],["Samples / code issue","samplesCodeIssue","thumb-down"],["Other","otherDown","thumb-down"]],["Last updated 2024-12-02 UTC."],[[["\u003cp\u003eThe \u003ccode\u003eLockService\u003c/code\u003e enables scripts to ensure that only one instance of a script executes a specific code section at a time, preventing collisions when accessing shared resources.\u003c/p\u003e\n"],["\u003cp\u003eIt's particularly useful for scenarios like form submissions and triggers where multiple users might concurrently modify shared data, like incrementing ticket numbers.\u003c/p\u003e\n"],["\u003cp\u003eThe service provides methods for acquiring (\u003ccode\u003ewaitLock\u003c/code\u003e, \u003ccode\u003etryLock\u003c/code\u003e), releasing (\u003ccode\u003ereleaseLock\u003c/code\u003e), and checking the status (\u003ccode\u003ehasLock\u003c/code\u003e) of locks.\u003c/p\u003e\n"],["\u003cp\u003eUsing locks prevents data corruption or inconsistencies that could arise from simultaneous access to shared resources.\u003c/p\u003e\n"],["\u003cp\u003eFor efficient resource management, it's recommended to release the lock as soon as exclusive access is no longer needed using \u003ccode\u003ereleaseLock()\u003c/code\u003e.\u003c/p\u003e\n"]]],[],null,["# Class Lock\n\nLock\n\nA representation of a mutual-exclusion lock.\n\nThis class lets scripts make sure that only one instance of the script executes a given\nsection of code at a time. This is particularly useful for callbacks and triggers, where a user\naction might cause changes to a shared resource and you want to ensure that there aren't\ncollisions.\n\nThe following example shows how to use a lock in a form submit handler.\n\n```javascript\n// Generates a unique ticket number for every form submission.\nfunction onFormSubmit(e) {\n const targetCell = e.range.offset(0, e.range.getNumColumns(), 1, 1);\n\n // Gets a script lock before modifying a shared resource.\n const lock = LockService.getScriptLock();\n // Waits for up to 30 seconds for other processes to finish.\n lock.waitLock(30000);\n\n const scriptProperties = PropertiesService.getScriptProperties();\n\n const ticketNumber =\n Number(scriptProperties.getProperty('lastTicketNumber')) + 1;\n scriptProperties.setProperty('lastTicketNumber', ticketNumber);\n\n // Releases the lock so that other processes can continue.\n lock.releaseLock();\n\n targetCell.setValue(ticketNumber);\n}\n```\nWithout the Lock service, if two users submit the form at approximately the same time, the ticket numbers could end up the same, since the `last``Ticket``Number` property could change after it was read from the `Script``Properties` but before the new value was written back. \n\n### Methods\n\n| Method | Return type | Brief description |\n|-------------------------------------------------|-------------|-------------------------------------------------------------------------------------------------------|\n| [hasLock()](#hasLock()) | `Boolean` | Returns true if the lock was acquired. |\n| [releaseLock()](#releaseLock()) | `void` | Releases the lock, allowing other processes waiting on the lock to continue. |\n| [tryLock(timeoutInMillis)](#tryLock(Integer)) | `Boolean` | Attempts to acquire the lock, timing out after the provided number of milliseconds. |\n| [waitLock(timeoutInMillis)](#waitLock(Integer)) | `void` | Attempts to acquire the lock, timing out with an exception after the provided number of milliseconds. |\n\nDetailed documentation\n----------------------\n\n### `has``Lock()`\n\nReturns true if the lock was acquired. This method will return false if [tryLock(timeoutInMillis)](#tryLock(Integer)) or\n[waitLock(timeoutInMillis)](#waitLock(Integer)) were never called, timed out before the lock could be retrieved, or if [releaseLock()](#releaseLock()) was called.\n\n```javascript\nconst lock = LockService.getScriptLock();\nlock.tryLock(10000);\nif (!lock.hasLock()) {\n Logger.log('Could not obtain lock after 10 seconds.');\n}\n```\n\n#### Return\n\n\n`Boolean` --- true if the lock was acquired, false otherwise\n\n*** ** * ** ***\n\n### `release``Lock()`\n\nReleases the lock, allowing other processes waiting on the lock to continue. The lock is\nautomatically released when the script terminates, but for efficiency it is best to release it\nas soon as you no longer need exclusive access to a section of code. This method has no effect\nif the lock has not been acquired.\n\nNote that if you are working with a spreadsheet, you should call SpreadsheetApp.flush()\nprior to releasing the lock, to commit all pending changes to the spreadsheet while you still\nhave exclusive access to it.\n\n```javascript\nconst lock = LockService.getScriptLock();\nlock.waitLock(10000);\n// Do some work on a shared resource.\nlock.releaseLock();\n```\n\n*** ** * ** ***\n\n### `try``Lock(timeoutInMillis)`\n\nAttempts to acquire the lock, timing out after the provided number of milliseconds. This method\nhas no effect if the lock has already been acquired.\n\n```javascript\nconst lock = LockService.getScriptLock();\nconst success = lock.tryLock(10000);\nif (!success) {\n Logger.log('Could not obtain lock after 10 seconds.');\n}\n```\n\n#### Parameters\n\n| Name | Type | Description |\n|-----------------------|-----------|-------------------------------------------------------|\n| `timeout``In``Millis` | `Integer` | how long to wait to acquire the lock, in milliseconds |\n\n#### Return\n\n\n`Boolean` --- true if the lock was acquired, false otherwise\n\n*** ** * ** ***\n\n### `wait``Lock(timeoutInMillis)`\n\nAttempts to acquire the lock, timing out with an exception after the provided number of\nmilliseconds. This method is the same as [tryLock(timeoutInMillis)](#tryLock(Integer)) except that it throws an exception\nwhen the lock could not be acquired instead of returning false.\n\n```javascript\nconst lock = LockService.getScriptLock();\ntry {\n lock.waitLock(10000);\n} catch (e) {\n Logger.log('Could not obtain lock after 10 seconds.');\n}\n```\n\n#### Parameters\n\n| Name | Type | Description |\n|-----------------------|-----------|-------------------------------------------------------|\n| `timeout``In``Millis` | `Integer` | how long to wait to acquire the lock, in milliseconds |\n\n#### Throws\n\n\n[`Error`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error) --- if the method timed out before the lock was acquired"]]