VBScriptの「書き込みエラー(70)」を封殺せよ!指数バックオフとジッターによる堅牢なログ制御術
こんにちは。現場で血反吐を吐きながらシステムを安定稼働させてきたエンジニアの視点から、今日はVBScriptの「地雷」の一つ、「書き込み時の排他ロック競合」を華麗に回避する方法を伝授します。
VBScriptでログを吐いていると、突如として襲いかかる「実行時エラー: 70 (書き込み禁止)」。これは、他のプロセスがファイルを掴んでいる時に発生する、いわゆる「運ゲー」の状態です。
マクロの記録から一歩先へ進み、「止まらないスクリプト」を書くための極意、見ていきましょう。
—
なぜ、書き込みエラー(70)は発生するのか?
Windowsのファイルシステムは、誰かがファイルを開いている間、他の書き込みを弾くことがあります。特に、複数のバッチが同時にログを吐こうとしたり、ウイルス対策ソフトが裏でスキャンをかけていたりすると、この衝突は避けられません。
ここで多くの初学者がやるのが「とりあえず1秒待ってリトライ」という手法。しかし、複数のプロセスが同じタイミングで一斉にリトライを開始すると、再び衝突する「共鳴現象」が起きます。
これを防ぐのが、今回紹介する「指数バックオフ」と「ジッター(揺らぎ)」です。
—
実装の極意:指数バックオフ + ジッター
仕組みはシンプルです。
1. 指数バックオフ: リトライするたびに、待ち時間を「2倍、4倍、8倍」と指数関数的に増やします。
2. ジッター(揺らぎ): 待ち時間にランダムな数値を足します。これで、複数のプロセスが「同じタイミングで一斉に再試行する」確率を劇的に下げます。
堅牢な書き込み関数(コピペ用)
このコードをあなたのライブラリに組み込んでください。
‘ — 指定したファイルに追記する堅牢な関数 —
Function SafeAppendLog(filePath, message)
Dim fso, ts, retries, maxRetries, waitTime
Set fso = CreateObject(“Scripting.FileSystemObject”)
maxRetries = 5 ‘ 最大リトライ回数
retries = 0
Do While retries < maxRetries On Error Resume Next ' エラーを握りつぶして制御下に置く Set ts = fso.OpenTextFile(filePath, 8, True) ' 8: ForAppending If Err.Number = 0 Then ts.WriteLine Now & " : " & message ts.Close SafeAppendLog = True Exit Function Else ' エラー発生!エラー番号70(Permission Denied)かを確認 Err.Clear retries = retries + 1 ' 指数バックオフ: 2^retries 100ミリ秒 + ランダムな揺らぎ Randomize waitTime = (2 ^ retries) 100 + Int(Rnd 200) WScript.Sleep waitTime End If On Error GoTo 0 Loop SafeAppendLog = False ' 諦めた場合 End Function ' 実行例 If SafeAppendLog("C:\logs\app.log", "処理を開始しました") Then WScript.Echo "成功しました。" Else WScript.Echo "リトライ上限に達しました。書き込み失敗。" End If ---
コードのポイント解説
1. `On Error Resume Next` の正しい使い方
VBScriptでは、エラーが起きると即座にスクリプトが停止します。これを防ぐために、あえてエラーを一時的に無視し、直後に `Err.Number` をチェックすることで「ファイルが使えないなら、少し待ってからもう一度」という人間のような判断をさせています。
2. `Randomize` と `Rnd`
これが「ジッター」の正体です。`Int(Rnd 200)` により、0〜200ミリ秒のランダムな待ち時間が追加されます。全員が同じテンポでリトライするのを防ぐ、「渋滞を避けるための賢いドライバー」のような発想ですね。
3. `WScript.Sleep`
プロセスのCPUを占有せずに待機するための重要なメソッドです。これを入れないと、リトライのループが高速すぎてCPU使用率が跳ね上がり、かえって競合を助長します。
—
最後に:エンジニアとしての一歩先へ
今回学んだ「リトライロジック」は、単なるバグ回避ではありません。「システムが外部環境の影響をどう受け流すか」という設計思想そのものです。
VBScriptは古い言語と言われますが、こうした基本的な制御構造を理解していることは、将来的にPythonやPowerShellへステップアップする際にも必ずあなたの強力な武器になります。
「エラーは起きるもの」と前提に置き、それをいかに静かに、スマートに解決するか。その思考こそが、現場で信頼されるエンジニアの証です。
ここをクリアしたあなたは、もうマクロの記録をポチポチ押すだけのユーザーではありません。「実行環境を制御するエンジニア」です。自信を持ってくださいね!
