How to fix "There are too many LockService operations against the same script" error?

Viewed 5033

I have a public add-on that utilises Google Apps Script Lock Service to prevent reading a spreadsheet before writes are made.

var lock = LockService.getDocumentLock();
var success = lock.tryLock(240000); // 4 minutes
if (!success) {
console.warn('Could not obtain lock after 4 minutes.');
return;
}
//perform some function then release lock
lock.releaseLock();

I continue to receive the error message:

There are too many LockService operations against the same script.

Originally I thought this error was 'user based' and there was potentially a quota against the number of Lock Service operations per user, however I recently started seeing it appear more often against 30+ users in the past few days.

  • Is there a limit to the number of LockService operations per user or per script?
  • If so, what is the limit?

I don't see any reference to a quota within Google Apps Script quotas

Nor do I see any reference to a quota within the LockService documentation

3 Answers

There is a report about this: https://issuetracker.google.com/issues/112384851

It appears this might happen sporadically. A Google employee responded with the following:

Just to give an update to this: The Apps Script team recommends:

1) Use a try/catch block around the LockService call, and assume that an error means "lock was not acquired" (whatever that means for the logic the script is trying to do).

2) If "lock was not acquired" means "script should try again", then put a sleep in there of a few seconds (maybe even exponential backoff) before retrying the LockService operation.

We do not have any other solution for this at the moment and might have an update once certain changes are made to Apps Script.

This likely happens when there are multiple triggers trying to access the same Google Sheet simultaneously. Google Quota page doesn't document the exact limits anywhere but try reducing the number of triggers associated with the sheet and it should work.

I don't know the answer to the question (so I won't mark this answer as accepted), but here is my workaround.

Not the most elegant solution as it does not protect against all cases (triggers running in quick succession and triggers at times running out of sequence), so any guidance from the more experienced is appreciated.

try{

  for(var i=1; i<11; i++){ //attempt 10 times, then run and hope for the best
    var documentLock = PropertiesService.getDocumentProperties().getProperty('documentLock');
    if(documentLock){
    Utilities.sleep(20000); //if locked, sleep for 20 seconds
    console.log('Wait ' + i + ' for documentLock to be released.');
    }else{break;}
  }

  PropertiesService.getDocumentProperties().setProperty('documentLock', true);

  runSomeFunction()

}
catch(err){

  console.error(err);
  console.error(err["stack"]);

}
finally{

  PropertiesService.getDocumentProperties().deleteProperty('documentLock');

}
Related