Lock Serviceでスクリプトを堅牢にする (2/2): 逆引きGoogle Apps Script

2012 年 9 月 21 日 金曜日

LockServiceでは、並行で動作しているプロセスをロック(=休止状態)することができる。前回のスクリプトでは、複数人が同時に実行すると、データが破壊されてしまうケースを挙げたが、このページでは、それを回避する方法を紹介している。

Lock Serviceでスクリプトを堅牢にする (1/2)の続き。

▼LockServiceを採用したサンプルスクリプト

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
function getMyEventList2(){
  var lock = LockService.getPublicLock();  
  try{
    //30秒間ロック
    lock.waitLock(30000);
    var myCalendar = CalendarApp.getDefaultCalendar();
    var events = myCalendar.getEvents(
                  new Date('2010/1/1'), 
                  new Date('2012/1/1'));
 
    //取得した予定をスプレッドシートに出力
    var ss = SpreadsheetApp.getActiveSpreadsheet();
    var sheet = ss.getActiveSheet();
 
    //最終行から書き込み開始
    var start = sheet.getLastRow()+1;
    for(var i=0; i<events.length; i++){
      sheet.getRange('A'+(start+i)).setValue(events[i].getTitle());
    }  
 
    //ロックを解除
    lock.releaseLock();
    Browser.msgBox('書き込み完了!');
 
  }catch(e){
    //waitLockで指定した時間(30秒)以上ロックが解除されなかった場合
    if(e.message.indexOf('another process was holding the lock')>0){
      Browser.msgBox('他のプロセスがロックしています。しばらく待ってから、もう一度実行して下い。');
    }else{
      Browser.msgBox(e);
    }    
  }  
}

サンプルスクリプトの解説

    

行2 Lockインスタンスを生成。PrivateLockとPublickLockの違いについては後述
行5 5行目の{LockService}.waitLock()により、ロックをかけている。
22行目でロックが解除されるか、スクリプトが終了するまでの間に、別のユーザーがスクリプトを実行すると、行2で一旦プロセスが休止状態に入る。waitLockとtryLockの違いは後述。
行22 ロックを解除。明示的に解除しなくてもスクリプトが終了した時に自動で解除されるが、ロックする必要がなくなった時はできるだけ早く解除した方が良い。
行27 ユーザーAがロックをかけ、そのあとユーザーBがスクリプトを実行した場合、waitLockで指定した時間以内にロックが解除されなかった場合、ユーザーBのプロセスに対して例外がスローされる。e.message.indexOf(~) > 0では、例外メッセージが、indexOfで指定した文字列を含んでいるかどうかを判定している。

構文

LockService.PrivateLock

LockService.PublicLock

Lockインスタンスを生成する。

Private Lock
スクリプト実行ユーザーに対して、複数プロセスの実行を防止する。
Public Lock
実行ユーザーに関わらず、複数プロセスの実行を防止する。
PrivateLockでは、Aがロックをかけても、Bはそのロックを無視して処理を実行する。PublicLockでは、Aがロックをかけると、ロックが解除されるまでBは処理を実行することができない。

{Lock}.tryLock(timeoutInMilliseconds)

{Lock}.waitLock(timeoutInMilliseconds)

ロックを試みる。ロックが成功した場合、パラメータで指定したミリ秒ロックする。最大30000。(30秒)

waitLock
パラメータで指定した時間以上経過した場合、例外をスローする。
tryLock
パラメータで指定した時間以上経過した場合、falseをかえす。

{Lock}.releaseLock()

ロックを明示的に解除する。

スポンサードリンク

関連記事

コメント / トラックバック 1 件

コメントをどうぞ

トラックバック

このエントリーのトラックバックURL:

http://www.bmoo.net/archives/2012/09/314721.html/trackback