【GAS】appendRow()の同時実行は競合するのか

  • このエントリーをはてなブックマークに追加
  • LINEで送る

はじめに

GASでシート末尾に値を追加するappendRow()について、
同時に実行したら同じ行を編集してしまうのか、検証しました。
結論:同時実行は競合します。
以下、検証方法の紹介です。

コードと出力結果

function myFunction() {
  const sh = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("シート1");

  let now = dayjs.dayjs();
  while(now.format("HH:mm")!="09:30"){
    now = dayjs.dayjs();
  }

  sh.appendRow([dayjs.dayjs().format("YYYY/MM/DD HH:mm:ss")]);
  Utilities.sleep(300);
  sh.appendRow([dayjs.dayjs().format("YYYY/MM/DD HH:mm:ss")]);
  Utilities.sleep(300);
  sh.appendRow([dayjs.dayjs().format("YYYY/MM/DD HH:mm:ss")]);
  Utilities.sleep(300);
  sh.appendRow([dayjs.dayjs().format("YYYY/MM/DD HH:mm:ss")]);
  Utilities.sleep(300);
  sh.appendRow([dayjs.dayjs().format("YYYY/MM/DD HH:mm:ss")]);
}

4つのタブで同じスクリプトエディタを開き、実行します。
すると9:30になった瞬間同時に書き込みが走り、合計20行に値が入るはずです。
しかし、何度かやっても17~19行しか値が入りませんでした。
やはり20回の実行のうち、最終行を取得するタイミングが重なってしまうようでした。
気になる方はシートからエディタを開いてコピペして試してみてください。
(シートなので証拠になりませんが、イメージ図です。)
18行しか書き込まれていないイメージ図

対処方法はあるのか

appendRow()を使う限り、競合の可能性は捨てきれないでしょう。
appendRow()以外の方法で、絶対に競合を避けたい場合には、
GoogleDriveにファイルを保存する等の手段があります。

シート行に保存しようとしていたデータ1つ1つについて、
Drive上にJSONなどのファイルを設ければ、競合可能性を相当下げることができます。
ファイル名を日次+UUIDなどにしておけば、同名ファイルが生成されることもありません。
注意点として、それらのJSONを同時に変更可能な仕様にしてはいけません。

さいごに

GoogleAppsScriptを使う以上、
一部の処理ではどうしても競合が発生してしまいます。
上述のような打開策もありますが、仕様が分かりにくくなります。
外部のデータベースの利用なども視野に入れて仕様検討するのが無難かと思います。

  • このエントリーをはてなブックマークに追加
  • LINEで送る

コメントを残す

*