【実務・中級編】【リトライ機能付きログライター】FileSystemObject の書き込み競合(エラー502)を回避する安全な排他制御モジュール – VBScript (Visual Basic Scripting Edition)解析バイブル

スポンサーリンク

VBScriptを「おもちゃ」で終わらせない:書き込み競合を制する「指数バックオフ」実装術

業務自動化の現場で、VBScriptは今なお現役だ。しかし、多くのエンジニアが「実行時エラー: 70(書き込み禁止)」や、同時アクセスによるログの欠損に頭を抱えている。

なぜ彼らは失敗するのか? それは「ファイルシステムを排他的なリソースとして捉えていない」からに他ならない。

今回は、FileSystemObject (FSO) の脆弱性を補完し、現代のマルチタスク環境でも通用する「リトライ付きログライター」の設計思想を伝授する。

1. なぜ「単純な書き込み」は崩壊するのか

VBScriptで `OpenTextFile` を実行した瞬間、OSはファイルハンドルを確保しようとする。もし別プロセスがそのファイルを掴んでいれば、即座にエラーが返る。

多くの初心者は、ここで `On Error Resume Next` を使い、エラーを無視して終わらせる。しかし、それは「ログの消失」を容認する行為だ。業務システムにおいて「ログが消える」ことは、バグそのものよりも罪深い。

解決の鍵:指数バックオフ (Exponential Backoff)

単なる「1秒待って再試行」のループは、高負荷時にさらなる競合を生む。「待機時間を毎回倍増させる」という指数バックオフのアルゴリズムを導入することで、プロセス間の衝突を確率的に激減させるのがプロの作法だ。

2. 堅牢なログライター・モジュール

以下のコードは、単なる関数ではない。排他制御の失敗を許容しないための「プロフェッショナルなテンプレート」だ。

‘ — ログ出力モジュール —
‘ 競合を回避し、ログの安全な追記を保証する
Function SafeLog(strFilePath, strMessage)
Dim fso, ts, i, retryCount, delay
Set fso = CreateObject(“Scripting.FileSystemObject”)

retryCount = 5 ‘ 最大リトライ回数
delay = 100 ‘ 初期待機時間(ミリ秒)

For i = 1 To retryCount
On Error Resume Next
‘ ForAppending(8)で開く。失敗したらエラーが発生
Set ts = fso.OpenTextFile(strFilePath, 8, True)

If Err.Number = 0 Then
ts.WriteLine Now & ” : ” & strMessage
ts.Close
SafeLog = True
Exit Function
Else
‘ 競合発生時はランダム要素を加えた指数バックオフ
Err.Clear
WScript.Sleep delay + (Rnd 50)
delay = delay 2
End If
On Error GoTo 0
Next

‘ リトライ上限に達した場合のハンドリング
WScript.Echo “Critical Error: ログ書き込み失敗 – ” & strFilePath
SafeLog = False
End Function

3. 実装の極意:ここが設計の分かれ道

① オブジェクトは最小単位で管理せよ

`FileSystemObject` をグローバルに使い回すのは避けろ。メモリリークや不正な状態の保持を防ぐため、ログ書き込みの関数内で生成し、終わったらスコープを外れるように設計する。VBScriptのガベージコレクションを信じすぎるな。

② 「排他制御」は最後の砦

本来、高度な並列処理が必要ならデータベースやSQL Server Expressなどを選定すべきだ。しかし、VBScriptを選択せざるを得ない現場では、この「リトライ機構」が唯一の防波堤となる。

③ ログの粒度と運用

ログファイルが巨大化すると、ファイルシステムのロック時間も長くなる。

  • 日付ごとにファイルを分割する(`log_20231027.txt` 等)
  • 1ファイルあたりの上限サイズを設け、ローテーションする

これらを実装することで、I/O負荷を分散させ、競合確率を根本から下げることができる。

4. 最後に:エンジニアとしての矜持

VBScriptは古いが、その挙動を深く理解し、泥臭い排他制御をコードに落とし込む作業は、モダンな言語を使う際にも極めて重要な「システム設計の基礎体力」となる。

コードをコピペして動かすだけでなく、「なぜ今、この待機時間が必要なのか」を思考すること。その問いの先に、あなたを「スクリプトを書く人」から「自動化エンジニア」へと進化させる道がある。

さあ、あなたの自動化ツールを、誰にも文句を言わせない堅牢なシステムへと磨き上げろ。

タイトルとURLをコピーしました