Google Apps Scriptで、複数の実行が同時に同じデータを触ると、データが壊れることがあります。
それを防ぐのが、LockServiceです。
公式のリファレンスから、3種類のロックと、取得と解放の使い方を整理しました。
- getScriptLock:スクリプト全体で、同時に1人だけ通す
- getDocumentLock:そのドキュメントで、同時に1人だけ通す
- getUserLock:そのユーザー自身の実行だけを排他にする
- 取得したロックは、tryLockかwaitLockを呼ぶまで有効にならない
LockServiceの説明は公式資料に基づき、掲載コードの分岐はローカルで検証しています。
仕様や数値は変わることがあるので、最新は公式ページで確かめてください。
3種類のロック
| メソッド | 排他の範囲 | 戻り値 |
|---|---|---|
| getScriptLock() | 全ユーザーの、スクリプト全体 | Lock |
| getDocumentLock() | 現在のドキュメントの全ユーザー | Lock、またはnull |
| getUserLock() | 現在のユーザーだけ。別のユーザーは同時に実行できる | Lock |
getDocumentLock は、ドキュメントの外で動いているときは、nullを返します。
ロックを取る・待つ・放す
ロックのオブジェクトを取っただけでは、ロックはかかりません。
tryLockかwaitLockを呼んで、はじめて取得されます。
| メソッド | 動き |
|---|---|
| tryLock(ms) | 指定したミリ秒まで待つ。取れたらtrue、時間切れならfalse |
| waitLock(ms) | 指定したミリ秒まで待つ。時間切れのときは例外を投げる |
| hasLock() | 取得できていればtrue |
| releaseLock() | ロックを放し、待っている処理を進める |
すでに取得しているときに tryLock を呼んでも、効果はありません。
書き方の例
同じスクリプトの実行が重なったときに、A1の値を読み取って1増やす処理を、ロックの取得から解放までの間にまとめます。
function incrementCounter() {
const lock = LockService.getScriptLock();
if (!lock.tryLock(5000)) {
throw new Error('別の実行が処理中です。少し待ってから実行してください。');
}
try {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('ロック練習');
if (!sheet) throw new Error('「ロック練習」シートを作成してください。');
const cell = sheet.getRange('A1');
const current = cell.getValue();
if (typeof current !== 'number' || !Number.isSafeInteger(current) || current < 0 || current >= Number.MAX_SAFE_INTEGER) {
throw new Error('A1には0以上の整数を入力してください。');
}
cell.setValue(current + 1);
SpreadsheetApp.flush();
} finally {
lock.releaseLock();
}
}この例の待ち時間は5秒で、取得できなければセルを書き換えずエラーにします。
- 練習用スプレッドシートに「ロック練習」というシートを作り、A1に数値の0を入力します。
- 「拡張機能」→「Apps Script」でコードを保存し、incrementCounterを実行します。
- 実行が完了するたびにA1が1、2と増えることを確認します。
- 元に戻すときは実行を止めてA1を0に戻します。
放すときの注意
- スクリプトが終わればロックは自動で放されるが、手動で放すほうが効率がよい
- 取得していないロックを放しても、効果はない
- スプレッドシートを扱うときは、放す前にSpreadsheetApp.flush()で変更を確定させる
どれを選ぶか
- フォームの送信のように、誰が動かしても同じデータを触るなら、getScriptLock
- 特定のドキュメントだけを守りたいなら、getDocumentLock
- 自分の実行どうしの重なりだけを防ぎたいなら、getUserLock
待機できる数やクォータとの関係は、今回確認できていません。
ロックで防げる変更の範囲
同じスクリプトで同じ種類のロックを取得する処理どうしが対象です。
別のスクリプトや、人がシートを直接編集する操作まで禁止するものではありません。
読み取りをロック取得前へ移すと、古い値を使って上書きする可能性が残るため、読み取り・計算・書き込みをまとめて囲みます。
確認した範囲と公式資料
2026年10月2日に公式資料と掲載コードを照合しました。
コードの分岐はGoogleのサービスを代替したローカルテストで確認し、実サービスでの実行とは区別しています。
GAS上の認可・トリガー発火・同時実行は未検証です。
