特定の PoC 環境で、Dataverse 非同期ジョブのキュー待ちが最大13分に達したとき、タイムアウトは1件も発生しなかった。「2分制限のはずでは」と思ったとしたら、診断の起点が間違っている。

タイムアウトは実行時間にしかかからない。ログで見ている「総経過時間」は、キューに放り込んでから完了するまでの wall-clock であり、その大半が「拾われ待ち(ディスパッチ待ち)」である可能性がある。この区別が曖昧なまま診断すると、問題のないジョブを危険視するか、本当に問題のある実行時間の長さを見逃す。

結論を先に示す。Dataverse の AsyncOperation テーブルには CreatedOn / StartedOn / CompletedOn の3時刻フィールドがある。これを分離して計測すれば、総経過時間の内訳がわかり、タイムアウト診断が正確になる。


13分待っても、タイムアウトしない

Dataverse の非同期サービスは FIFO(先入れ先出し)のマネージドキューを持つ。ジョブが登録されると、キューに投入され、非同期サービスが「拾いに来る」まで待つ。この待ち時間はタイムアウトのカウントに含まれない。

Microsoft Learn の公式ドキュメント(Asynchronous service (Microsoft Dataverse)、2025年確認)には次の記述がある。

sending the request asynchronously doesn’t provide more execution time

非同期登録にしても、実行タイムアウト(プラグイン・ワークフロー共通で2分=120秒)は変わらない。制限されているのはあくまで「実行時間」であり、「キューに入ってから拾われるまでの待ち時間」は制限の対象外だ。

レストランの席待ちに例えると、タイムアウト2分は「席に着いてから注文・食事・会計までの時間制限」だ。席待ちで40分並んでいても、それはタイムアウトに数えられない。13分のキュー待ちがあっても、その後の実行が2分以内に収まれば、タイムアウトは発生しない。

ただし、上記の「最大13分のキュー待ち」は特定の PoC 環境での観察値であり、本番環境や他製品での再現を保証するものではない。


判断軸:拾われ待ちと実行時間は別物だ

非同期ジョブの経過時間は、大きく2つに分解できる。

区間内容タイムアウト対象か
拾われ待ちキュー投入 → 実行開始対象外
実行時間実行開始 → 実行完了対象(2分・120秒)

タイムアウト診断で見るべきは、右列が「対象」の実行時間だけだ。ログの総経過時間を見ていると、拾われ待ちの長さがそのまま「危険なシグナル」に見えてしまう。逆に、実行時間が2分に近づいていても、総経過時間が短ければ見過ごす可能性がある。

計測の単位を間違えると、診断の方向が最初から狂う。


AsyncOperation テーブルで3時刻を分離する

Dataverse の AsyncOperation テーブル(System Job (AsyncOperation) table/entity reference、2025年確認)には、以下のフィールドが存在する。

フィールド意味診断での役割
CreatedOnジョブ作成(キュー投入)時刻拾われ待ちの開始点
StartedOn実行開始時刻拾われ待ちの終点・タイムアウトカウント開始
CompletedOn実行完了時刻実行時間の終点
ExecutionTimeSpan実行時間(数値)タイムアウト評価の直接対象

計算式はシンプルだ。

  • 拾われ待ち = StartedOnCreatedOn(タイムアウト対象外)
  • 実行時間 = ExecutionTimeSpan(= StartedOnCompletedOn の差、タイムアウト対象)

ログで見えている「総経過時間(wall-clock)」は CompletedOnCreatedOn だ。これは拾われ待ちと実行時間の合算であり、タイムアウトの診断には直接使えない。

なお、ExecutionTimeSpan がタイムアウトによる中断時にどのような値になるかは、フィールド定義の記述範囲では確認できていない。診断の主軸として使う場合は、正常完了ジョブへの適用に限るのが無難だ。


2つの誤診パターン

パターン1:総経過時間が長い → 「危険」の早合点

総経過時間(wall-clock)を見て「これはタイムアウトが心配だ」と判断するケース。実際には拾われ待ちが大半で、実行時間は制限内に収まっている場合がある。

対処は前述の3フィールド分離だ。ExecutionTimeSpan を確認し、2分以内なら実行側の問題ではない。キューの混雑(拾われ待ちの長さ)は別の問題として切り分ける。

パターン2:「成功ジョブは速い」という思い込み

成功したジョブを振り返ると「そんなに時間はかかっていない」と感じる場合がある。ただし、この直感には構造的なバイアスがかかっている可能性がある。

Dataverse では、成功した非同期ジョブは既定で30日後に自動削除される(SucceededSystemJobPersistenceInDays = 30日・全環境に出荷時設定済み、Delete completed system jobs…、2025年確認)。ワークフローでは「完了したワークフロー ジョブを自動削除する」オプションを有効化すると、成功時に即時削除される。

一方、失敗ジョブは既定で60日間保持される。

つまり、手元に残っているデータは失敗ジョブに偏っている。「成功ジョブのサンプル」が30日で消えていくため、成功ジョブが速かったのか遅かったのかを後から確認できない状態がデフォルトだ。「成功は速い」という印象は、データの偏りから来ている可能性がある。


計測の手順

以下の手順で、診断を3時刻分離に切り替える。

Step 1:AsyncOperation テーブルへのアクセスを確保する

Power Apps のテーブルビューまたは OData クエリで asyncoperation テーブルを参照する。環境のシステム管理者権限が必要になる場合がある。

Step 2:対象ジョブを絞り込む

  • OperationType(操作種別)でプラグイン・ワークフローを絞り込む
  • StatusCode(状態コード)で成功・失敗・タイムアウトを区別する
  • 分析対象の時間帯で CreatedOn の範囲指定を行う

Step 3:3時刻を列として取得し、差分を計算する

指標計算診断での意味
拾われ待ちStartedOnCreatedOnキュー混雑の可視化
実行時間ExecutionTimeSpanタイムアウト2分との比較
総経過時間CompletedOnCreatedOn参考値(診断の主軸には使わない)

Step 4:ExecutionTimeSpan を2分(120秒)と比較する

  • 2分以内 → 実行時間は制限内。タイムアウトリスクは低い
  • 2分に近い値が常態化している → 実装の見直しを検討する
  • 拾われ待ちが長い → キューの混雑・処理能力の問題。実行タイムアウトとは別に対処する

なお、2分制限はプラグイン・ワークフロー共通の値で、2025年時点の公式ドキュメントで確認している。クラウドサービスのため個別バージョンはなく、仕様は変更される可能性がある。最新値は Microsoft Learn のドキュメントで確認すること。


計測できていない状態に気づく

3時刻分離を試みたとき、StartedOn が NULL になっているジョブがあれば、そのジョブはまだ実行されていないか、実行前にキャンセルされている。また、成功ジョブが既定で30日後に自動削除される設定のため、過去の成功ジョブを遡って分析しようとしても、データが存在しない場合がある。

「データがない」は「問題がなかった」ではない。何が計測できていて、何が計測できていないかを先に確認する。削除設定の変更・代替ログ収集手段については、別途環境の管理者と確認する必要がある。


まとめ

Dataverse 非同期ジョブのタイムアウト診断は、CreatedOn / StartedOn / CompletedOn の3時刻を分離して初めて成立する。総経過時間(wall-clock)は拾われ待ちと実行時間の合算であり、タイムアウトの制限は実行時間にしかかからない。


次の一歩:AsyncOperation テーブルを Power Apps のテーブルビューまたは OData で開き、ExecutionTimeSpanStartedOn / CreatedOn の差を並べた一覧を作る。それだけで診断の精度が変わる。

関連記事:非同期ジョブが遅い原因を「渋滞構造」から診断する方法は「並列を増やすと遅くなる理由と、直列ボトルネックを解消する3つの対策」で扱っている。バルク化しても速くならない場合の確認先は「Dataverse で CreateMultiple を使っても速くならないとき、受け手のプラグインを確認する」を参照。