2013-02-26 3 views
2

: -LockService 모호성

그래서 쿼리가 주위에 "현재 사용자에 대한 동시 실행하여 코드의 섹션에 동시 액세스를 방지하는 잠금을 가져옵니다 getPublicLock()"https://developers.google.com/apps-script/service_lock 그것은한다고 의견 : "코드 부분". 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()이 나타나는 줄 번호입니까, 아니면 주변 함수입니까?

답변

2

공개 잠금과 개인 잠금은 하나만 있습니다.

여러 개의 잠금을 사용하려면 일종의 명명 된 잠금 서비스를 직접 구현해야합니다. 스크립트 데이터베이스 기능을 사용하여 아래 예,이 데이터베이스 것으로 가정

  1. :

    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(); 
    

    참고 :이 서비스를 사용하려면

    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; 
        } 
        } 
    } 
    

    , 우리는 뭔가를 할 것 db.save() 작업은 본질적으로 분할 할 수 없습니다. 그렇지 않으면 정상적인 사용에 큰 문제가 발생하기 때문에 반드시 있어야한다고 생각합니다.

  2. 시간이 밀리 초이기 때문에 둘 이상의 작업이 동일한 타임 스탬프로 잠금을 시도 할 수 있다고 가정해야합니다. 그렇지 않으면 함수가 단순화 될 수 있습니다.

  3. 실행 시간 제한으로 인해 스크립트가 중지되므로 잠금을 1 분 이상 유지하지 않는 것으로 가정합니다 (그러나 이것을 변경할 수 있습니다).

  4. 크래시 된 스크립트의 오래된 잠금으로 인해 복잡해 지도록 저장하려면 1 분 이상 된 모든 잠금을 데이터베이스에서 정기적으로 제거해야합니다.

+0

이 답변이나 시나리오는 여전히 정확한 것입니까? 별도의 잠금 인스턴스가 별도의 함수로 사용될 수 있는지 확인하려고합니다. ('.getPublicLock()'이 더 이상 존재하지 않는 것처럼 보이지만,'getScriptLock()'은 그렇습니다). 그래서'var lock_01 = LockService.getScriptLock();'은'function_01()'에서 사용되지만'var lock_02 = LockService.getScriptLock();'은'function_02()'에서 사용될 수 있습니까? – user1063287