メインコンテンツへスキップ

Business Ruleはどの順番で動くか:incidentの39本を並べて確かめる


    incidentテーブルには、標準だけでBusiness Ruleが39本設定されています。1件のインシデントを更新するたびに、この39本のどれかが動き、条件に合えばスクリプトが走ります。

    では、39本のうちどれが最初に動くのか。同じタイミングで複数本が対象になったとき、実行順はどう決まるのか。フォームで見えるのは名前と有効/無効くらいで、実行順そのものは一覧画面から読み取りにくくなっています。

    この記事で分かること。

    • Business Ruleの実行順を決める2つの軸(when と order)の役割

    • incidentの39本を when 別に数えた本数と、一覧画面での確かめ方

    • 画面のラベルとスクリプトで指定する内部値が食い違う選択肢と、そのうち1件が非推奨扱いという実測

    • 同じ order の値を持つBusiness Ruleが実際に何本並んでいるか

    この記事は、ServiceNow の PDI(Personal Developer Instance、無料の個人検証環境)Zurich リリース・OOTB(初期設定)の一覧画面・フォーム・sys_choice の実機表示で確認した実測メモです(確認日 2026-08-08)。本番環境では追加・変更されたBusiness Ruleの分だけ本数や順序が変わります。

    公式ドキュメントで押さえる基本

    実機の画面を見る前に、when と order という2つの設定の役割を確認します。ここはServiceNowのBusiness Ruleドキュメントで説明されている公式の仕様です。

    when は「データベース操作のどのタイミングで動くか」を表す軸です。選択肢は display・before・after・async の4種類。

    • display … フォームを開いてレコードを画面に表示する直前に動きます。DBは更新しません。クライアントスクリプトに値を渡す g_scratchpad の準備によく使われます。

    • before … レコードがDBに書き込まれる前に動きます。値の補正やバリデーションに使う場面が多いタイミングです。

    • after … レコードがDBに書き込まれた後に動きます。関連レコードの更新や通知のトリガーに使われます。

    • async … after と同様に書き込み後ですが、スケジューラのキューに積まれて別トランザクションで動きます。処理が終わるのを待たずに元の処理を返せます。

    display→before→after→asyncという並び自体は、実行順に関するAPIリファレンスにも記載のある製品仕様です。テーブルや環境によって変わるものではありません。

    order は「同じ when の中で何番目に動くか」を表す数値です。小さい値ほど先に評価されます。Business rule use casesのドキュメントでも、複数のBusiness Ruleを組み合わせる場合はorderで順序を制御すると解説されています。

    この2軸は独立しています。when が違えば order の値がいくら近くても実行タイミングは別です。逆に when が同じなら、order の数値だけで前後が決まります。

    ここまでが仕様としての基本です。ここから先は、incidentテーブルの実機でこの2軸が実際にどう使われているかを、一覧画面とフォームで確かめていきます。

    実機で確かめる

    一覧をOrder順で見る

    Business Rules の一覧画面で Table = incident を条件に絞り、Order列でソートすると次のようになります。


    画像

    この一覧はTable = incidentで絞り込み、Order列を昇順にソートした状態です。列にはName・Active・Table・Application・Orderが並んでいます。並べ替えの結果、order0の2本が最初に来ます。名前はCopy State to Incident StateとCopy Incident State to Stateです。続いてSet WorkNote as created from Interaction(order10)が並びます。その次がincident events(order50)です。さらにDerive State value from Parent Incident(order90)と続き、order100のグループに入っていきます。

    Application列はすべてGlobalです。標準のincidentに設定されたBusiness Ruleは、追加のスコープアプリケーションではなくグローバルスコープに置かれていることが、この列からも分かります。

    Whenでグループ化して内訳を見る

    同じ一覧をWhen列でグループ化すると、when別の本数が一目で分かります。


    画像

    表示されるグループは次の4つです。


    画像

    before が24本ともっとも多く、次いで after が11本、display が3本、async は1本でした。合計すると39本になり、画面右上の「39 total Business Rules」と一致します。

    display が3本という数字は、意外に思われるかもしれません。display Business Ruleはフォームを開く直前に動き、DBを更新しません。この性質から、他の3種類より使われる場面が少ない機能です。ただし今回のincidentには3本が確かに設定されています。名前はSet WorkNote as created from Interaction・Load incident models into scratchpad・VIP scratchpadです。いずれも名前に「scratchpad」や「WorkNote」が入っています。クライアントスクリプト側へ値を渡す準備という、display本来の使われ方に沿った名前です。

    グループ名の表記にも注目してください。asyncのグループは「async (deprecated: not run during upgrade)」というラベルになっています。この理由は次の節で分かります。

    内部値とラベルの違いをsys_choiceで見る

    ここで実機を触るとつまずくポイントがあります。when の画面ラベルと、スクリプトで条件に使う内部値が一致しません。sys_choice で when の選択肢を開くと、次のようになっています。


    画像

    選択肢は5件あります。整理すると次のとおりです。


    画像

    before と after は内部値もラベルも同じですが、display は内部値が before_display です。GlideRecordのクエリで addQuery('when', 'display') と書いても0件になります。正しくは addQuery('when', 'before_display') です。

    もうひとつ、この一覧でしか分からない事実があります。asyncに対応する内部値は2つ存在します。async_always(Inactive=false、ラベルは「async」)と、async(Inactive=true、ラベルは「async (deprecated: not run during upgrade)」)です。incidentに設定されている唯一のasync業務ルール、Auto assessment business ruleは、有効な async_always ではなく非推奨の async を使っています。前節のグループ一覧で「async (deprecated: not run during upgrade)」という長いラベルが出ていたのは、このためです。選択肢自体は非推奨でも、既存のレコードがその値を持っていれば表示・実行には影響しません。

    フォームのどこで設定するか

    Business Ruleの新規作成フォームを開くと、次の画面になります。


    画像

    上部には製品自身の説明文があります。要約すると「レコードの表示・挿入・削除・問い合わせのタイミングで動くサーバーサイドスクリプト」というBusiness Ruleの定義です。基本の入力項目はName・Table・Application・Active・Advancedの5つです。「When to run」タブには、Insert・UpdateのチェックボックスとFilter Conditions・Role conditionsが並びます。

    ここで気づくのは、ここまで説明してきたWhen(display/before/after/async)とOrderの入力欄が、この画面には見当たらないことです。理由はAdvancedチェックボックスにあります。Advancedをオンにすると、When・Order・Delete・Queryを含む詳細な設定に画面が切り替わります。オフのままだと、Insert・Updateという操作の種類だけを選ぶ簡易的な作り方になり、Whenやorderを明示的に指定する場面自体が現れません。

    つまり、Business Ruleを新規に作るとき、Advancedを意識しないまま保存すると、Whenやorderの値はデフォルトのまま(当時作成した動作の裏側で決まる値)になります。一覧画面でWhenやOrderの列を見て「あれ、このルールはいつ作ったんだっけ」と迷うことがあれば、作成時にAdvancedをオンにしていたかどうかを疑う価値があります。

    Orderの分布

    最後に、When列ではなくOrder列でグループ化した画面を見ます。


    画像

    13個のOrder値にグループが分かれており、もっとも大きいのはOrder:100の21件です。39本中21本、半数以上がここに集中しています。次に多いのがOrder:200の3件、Order:101とOrder:999とOrder:1,000がそれぞれ2件で、残りは1件ずつです。もっとも大きい値はOrder:1,000,000の1件でした。

    when別の内訳まで含めて整理すると、次のようになります。


    画像

    Order:100の21件は、before13本・after6本・display2本の合算です。同じ100という値でも、実行されるタイミング(when)自体は別々なので、この21本が同時に競合するわけではありません。実際に同じタイミングで並ぶのは、before同士の13本、after同士の6本、display同士の2本という単位になります。

    orderの付け方の指針

    ここからは実測値そのものではなく、運用上の考え方です。

    before の24本のうち、order=100 だけで13本を占めています。動作としては問題なくても、新しくBusiness Ruleを追加するときに困る場面が出てきます。order=100の13本のどこに割り込ませるべきか、判断材料が一覧からは読み取れません。

    対策として考えられるのは、order の数値に意味を持たせて空きを作っておくことです。たとえば次のように帯を分けておく方法があります。

    • 値の正規化・補正 … 0〜50

    • 通常のバリデーション … 100〜500

    • 他レコードへの影響が大きい処理 … 1000以上

    こうしておけば、新しいBusiness Ruleを足すときにどこへ置くか迷いません。標準機能の order=100 のような密集も避けられます。

    beforeの実行順を order で並べる

    before の実行順を order 昇順で並べると、次のようになります。


    画像

    order=0 には Copy Incident State to State と Copy State to Incident State の2本があります。名前が対になっており、フィールドの値を相互にコピーする処理です。もっとも早い段階で動かす必要がある、単純な値の同期に使われていると考えられます。

    order=1,000,000 という飛び抜けた値にも、同名の Copy Incident State to State が登場します。同名でも別レコード(別のBusiness Rule)であり、片方は最初に、もう片方は最後に動く設定です。同じ名前を持つルールが、実行順としては最初と最後という正反対の位置に置かれています。

    他のBusiness Ruleの実行結果に依存する処理を書く場合は、同じ order の値を避け、依存先より確実に大きい order を明示的に設定しておくほうが安全です。同じ order 内の実行順がどう決まるかは、一覧の並びだけでは確認できていません。依存関係を order の偶然の並びに任せるのは避けたほうがよいと考えられます。

    afterとasyncの実行順

    after の実行順は次のとおりです。


    画像

    SNC - ITIL - Close Related という名前のBusiness Ruleが active=0(無効)のまま一覧に含まれています。sys_script に登録されているレコードは、有効・無効を問わず一覧に出てきます。一覧に出てくること自体は「設定されている」を意味するだけで、「動いている」を意味しません。実行順を調べるときは、order と合わせて active の値も必ず確認する必要があります。

    async は1本だけで、Auto assessment business rule という名前、order=300 でした。前段で触れたとおり、内部値は非推奨の async です。after とは別トランザクションの、スケジューラのキューで動く処理がひとつだけ設定されている、という状態です。

    つまずきやすい点

    実機を触っていて引っかかった点を4つにまとめます。

    1. when の内部値は画面ラベルと違う。 display は before_display です。スクリプトで addQuery('when', ...) を書くときは、sys_choice の対応表を確認してから内部値を入れてください。

    2. asyncには非推奨の内部値がある。 async_always(有効)と async(非推奨・inactive=true)の2つが選択肢として存在します。既存のBusiness Ruleがどちらを使っているかは、名前だけでは判断できません。

    3. 一覧に出ても動いていないBusiness Ruleがある。 SNC - ITIL - Close Related のように active=0 のレコードもクエリに含まれます。実行順を追うときは active も同時に見る癖をつけたほうが安全です。

    4. Advancedをオフにしたままだと、WhenやOrderの入力欄が出てこない。 新規作成フォームはデフォルトでInsert・Updateのチェックボックスだけの簡易画面です。実行タイミングや順序を意図して設計したいときは、Advancedをオンにする必要があります。

    FAQ

    Q1. orderの数値は小さいほど先に動きますか。
    はい。同じ when の中では order の値が小さいレコードから先に評価されます。今回の実測でも before の最小値は0(Copy Incident State to State など)で、最初に動く設定になっていました。

    Q2. 同じorderが複数あったら、実行順は決まっていますか。
    一覧の並び順だけでは確認できていません。今回はOrder列・When列でのソートやグループ化を確認しましたが、これは表示上の並べ替えです。実際のランタイムでの実行順は別途の確認が必要で、この記事では扱っていません。

    Q3. display Business Ruleは何に使いますか。
    フォームを開く直前に動き、DBは更新しません。今回のincidentには3本あります。名前はSet WorkNote as created from Interaction・Load incident models into scratchpad・VIP scratchpadです。いずれもクライアントスクリプトへ値を渡す準備に使われていると読めます。

    Q4. beforeとafterの他に、条件を絞る方法はありますか。
    Business Ruleのフォームには「Filter Conditions」があり、特定のフィールドの値が変化したときだけ動かす、といった絞り込みができます。今回はWhenとOrderの集計が目的のため、条件(condition)の中身までは扱っていません。

    Q5. Advancedをオンにしないと何が困りますか。
    When(display/before/after/async)とOrderの値を自分で指定できません。デフォルトの簡易画面のまま保存すると、実行タイミングや順序が意図どおりになっているか、フォーム上では確認しづらくなります。

    まとめ

    incidentのBusiness Ruleは39本あり、内訳は before 24・after 11・display 3・async 1でした。実行順は when と order の2軸で決まり、when は画面のラベルとスクリプトの内部値が一致しない選択肢があります。async に至っては、有効な内部値と非推奨の内部値が両方選択肢として存在し、既存の1本は非推奨のほうを使っていました。

    order は同じ when の中での順序を表す数値で、before では0から1,000,000まで幅があり、order=100だけで13本が並んでいました。when を横断したOrder列のグループ化では、order=100が21本ともっとも多い集まりでした。

    同じ order を持つBusiness Rule同士の実行順は、一覧の並びだけでは確認できませんでした。処理の前後関係が重要な場合は、order の値を離して明示的に優先順位を付けておくのが安全な運用と考えられます。

    用語

    • Business Rule(sys_script) … 特定のテーブルへの操作をトリガーに動くサーバーサイドスクリプト

    • when … Business Ruleが動くタイミング。画面上は display / before / after / async の4種類

    • order … 同じ when 内での実行順を決める数値。小さいほど先

    • collection … Business Ruleの対象テーブルを指すフィールド名

    • active … Business Ruleが有効かどうかのフラグ。0でも一覧には表示される

    • Advanced … Business Ruleフォームのチェックボックス。オンにするとWhen・Order・Delete・Queryなどの詳細設定が現れる

    参照した画面のURL

    • sys_script_list.do?sysparm_query=collection=incident^ORDERBYorder(incidentのBusiness Rule一覧をOrder順で表示)

    • sys_script_list.do?sysparm_query=collection=incident^GROUPBYwhen(Whenでグループ化)

    • sys_script_list.do?sysparm_query=collection=incident^GROUPBYorder(Orderでグループ化)

    • sys_choice_list.do?sysparm_query=name=sys_script^element=when^ORDERBYsequence(whenの選択肢定義)

    • sys_script.do?sys_id=-1(Business Ruleの新規作成フォーム)

    検証範囲とおことわり

    • 件数・order・active の値はPDI(Zurich / OOTB)でのincidentテーブルの実測です(確認日 2026-08-08)。本番環境や他テーブルでは異なります。同じPDIでも、確認日が数日違うだけで本数が変わることがあります(本記事も過去の実測から本数が変わっています)。

    • 同一order内の実際の実行順序は確認していません。一覧の並びは表示上のソートであり、実行ログでの検証はしていません。

    • display / before / after / async の間の順序(before→afterの前後関係など)はServiceNowの仕様として広く知られていますが、本記事では実行ログで直接は確認していません。

    • 各Business Ruleのフィルタ条件やスクリプト本文の中身は読んでいません。when・order・active・nameの範囲での確認です。

    • 条件によって実際には動かないBusiness Ruleの判別は行っていません。

    • Advancedをオンにした後のWhen/Order入力画面そのものは、実機のスクリーンショットでは確認していません。

    参考リンク

     
     
    ServiceNowのPDI(Personal Developer Instance)を実機で観察して、Noteに記事を書いています 実装・運用・教育の現場視点で淡々と記録中です リクエストがあればその記事も書きます 個人の観察日記です

    あなたへのおすすめ