在LockService文档中:https://developers.google.com/apps-script/service_lock它声明“getPublicLock() - 通过同时执行当前用户来获取阻止并行访问代码段的锁”
因此查询围绕评论:“代码段”。如果我有多个使用LockService.getPublicLock()的代码段,它们本质上是独立锁吗?
例如:
function test1() {
var lock = LockService.getPublicLock();
if (lock.tryLock(10000)) {
// Do some critical stuff
lock.releaseLock();
}
}
function test2() {
var lock = LockService.getPublicLock();
if (lock.tryLock(10000)) {
// Do some critical stuff
lock.releaseLock();
}
}
如果我有两个同时执行脚本的调用,一个用户访问test1()而另一个用户访问test2(),它们都会成功吗?或者在这篇文章中提到:http://googleappsdeveloper.blogspot.co.uk/2011/10/concurrency-and-google-apps-script.html只是脚本级别的锁?因此,对于这种情况,test1()或test2()中只有一个会成功,但不会同时成功。
如果它真的如文档所述,并且两者都会成功,那么什么表示“代码段”?它是LockService.getPublicLock()出现的行号还是周围的函数?
答案 0 :(得分:3)
只有一个公共锁,只有一个私人锁。
如果你想拥有几个锁,你需要自己实现某种命名的锁服务。下面的示例,使用脚本数据库功能:
var validTime = 60*1000; // maximum number of milliseconds for which a lock may be held
var lockType = "Named Locks"; // just a type in the database to identify these entries
function getNamedLock( name ) {
return {
locked: false,
db : ScriptDb.getMyDb(),
key: {type: lockType, name:name },
lock: function( timeout ) {
if ( this.locked ) return true;
if ( timeout===undefined ) timeout = 10000;
var endTime = Date.now()+timeout;
while ( (this.key.time=Date.now()) < endTime ) {
this.key = this.db.save( this.key );
if ( this.db.query(
{type: lockType,
name:this.key.name,
time:this.db.between( this.key.time-validTime, this.key.time+1 ) }
).getSize()==1 )
return this.locked = true; // no other or earlier key in the last valid time, so we have it
db.remove( this.key ); // someone else has, or might be trying to get, this lock, so try again
Utilities.sleep(Math.random()*200); // sleep randomly to avoid another collision
}
return false;
},
unlock: function () {
if (this.locked) this.db.remove(this.key);
this.locked = false;
}
}
}
要使用此服务,我们会执行以下操作:
var l = getNamedLock( someObject );
if ( l.lock() ) {
// critical code, can use some fields of l for convenience, such as
// l.db - the database object
// l.key.time - the time at which the lock was acquired
// l.key.getId() - database ID of the lock, could be a convenient unique ID
} else {
// recover somehow
}
l.unlock();
注意:
这假设数据库操作db.save()基本上是不可分割的 - 我认为必须这样做,因为否则在正常使用中会出现大麻烦。
因为时间以毫秒为单位,我们必须假设多个任务可以尝试使用相同的时间戳锁定,否则可以简化该功能。
我们假设锁定永远不会超过一分钟(但您可以更改),因为执行时间限制将会停止您的脚本。
您应该定期删除数据库中超过一分钟的所有锁,以防止它因崩溃的脚本中的旧锁而变得混乱。
答案 1 :(得分:0)
这个问题太旧了,现在“ getPublicLock()”不再可用。
根据https://developers.google.com/apps-script/reference/lock 此时LockServise呈现以下三个范围:
getDocumentLock():获取一个锁定,以防止当前文档的任何用户同时运行一段代码。
getScriptLock():获取一个锁定,以防止任何用户同时运行一段代码。
getUserLock():获取一个阻止当前用户同时运行代码段的锁。