メインコンテンツへスキップ
見出し画像

タスク管理モジュールのトラブル事例と解決


    Incident・Problem・Changeなど複数のプロセスで、同じ不具合が同時に起きることがあります。「担当者の項目が急に編集できない」「一覧に何も出ない」「保存が急に遅い」。プロセスごとに個別調査をしても原因が見つからないとき、原因は個々のテーブルではなく、63テーブルの共通基盤であるtask層にあります。Australia のPDIを実機で開き、task層が原因になる6つの症状と、その切り分け方を確認しました。

    検証環境:Australia PDI / OOTB / 2026-09-01 確認

    扱う症状

    • 複数プロセスに同時に出る症状から、原因の層を見分ける順序

    • task直接のACL・BusinessRule・UIポリシー・プロパティが63テーブルへどう波及するか

    • 新しいtask継承テーブルを作るときに起きがちな症状

    この記事で扱う症状

    • 同じ項目が全プロセスで編集できないのは、task.*のフィールドACL30件が原因

    • task.listで空に見える・全部見えるが割れるのは、既定動作がdenyだから

    • 保存が全プロセスで遅いときは、task直接BR33件の層を疑う

    • 関連リストの複製設定はChangeとIncidentだけにあり、Problemには無い

    • 継承だけでは新テーブルにSLAは付かない

    症状から原因へたどる順序

    taskを継承するテーブルの相談は、まず1つの軸で仕分けます。同じ症状がIncident・Problem・Changeなど複数プロセスで同時に起きているか、それとも1つのプロセスだけで起きているかです。


    画像

    複数プロセスに同時に出るなら、原因はtask直接の設定にある可能性が高くなります。taskを継承する63テーブルは、フィールド・ACL・BusinessRule・UIポリシーの多くをtaskから受け継ぐためです。1つのプロセスだけで起きるなら、そのプロセス固有の設定を先に疑います。


    画像

    この記事で扱う6つの症状は、すべて「複数プロセスで同時に起きる」側です。1プロセスだけで起きる症状の切り分けは、各プロセスのシリーズに譲ります。インシデントに限った症状の切り分けは、公開済みの記事にまとまっています。

    見落とされやすいのは、この軸そのものです。担当者はIncidentの相談を受けるとIncident側のACLやビジネスルールだけを確認しがちで、同じ時期にProblemやChangeでも同種の相談が来ていないかを見落とします。複数チャネルで問い合わせを受ける体制なら、直近の相談を横断で洗い出す一手間が近道になります。

    参考:インシデント管理モジュールのトラブル事例と解決 … Incident単体の症状はこちら

    同じ項目が全プロセスで編集できない

    症状:Incidentのpriority、Problemのpriority、Changeのpriorityなど、複数プロセスで同時に同じフィールドが保存できないという相談が来ます。特定の1人のユーザーだけで起きています。

    切り分け

    1. 症状が出るユーザーで、Incident・Problem・Changeそれぞれの該当フィールドを実際に開き、全プロセスで再現するかを確認する

    2. 全プロセスで再現するなら、そのユーザーが持つロールを確認する

    3. 1プロセスだけで起きるなら、そのテーブル固有のACL調査に切り替える(本記事の対象外)

    原因:task.*で始まるフィールドレベルACLは30件あります。assigned_to・priority・state・short_descriptionなど主要フィールドのwrite24件は、itilとtask_editorという2つの独立したロールのどちらかを持っていないと通りません。両方とも持たないユーザーは、63の子テーブルすべてで同時に書き込めなくなります。


    画像

    対処:対象ユーザーのロールを確認します。ITSM担当者に必要なのはitilです。PPMなど非ITSM系の担当者には、task_editorを内包する業務ロール(project_user等)を渡し、task_editor単独の付与は避けます。

    1件だけ編集できないなら、対象フィールドがapprovalのような専用ロール系である可能性があります。approval・approval_historyはapproval_adminのみが書き込めるため、itilを渡しても直りません。ロールを渡しても直らないときは、対象ユーザーでImpersonateして実際の画面を確認すると、権限拒否か別の原因かの切り分けが早くなります。

    参考:ロールを付けたのに見えない理由:ACL(sys_security_acl) … ACLの条件と評価順の基本

    参考:ServiceNowで「このレコードが見えない」は本当にACL拒否? Impersonate UserとSecurity Debugで実際に確かめる … 別ユーザーで実際に確かめる方法

    task.listが空に見える・全部見える

    症状:管理者が横断ビューtask.listを開くと、レコードがほとんど出ません。別の管理者が開くと、逆に想定より多く出ます。

    切り分け

    1. 症状が出るユーザーが、対象レコードのsys_class_nameに対応する読み取りロールを持つかを確認する

    2. 「全部見える」側の相談なら、そのユーザーがadminロールを持っていないかを先に確認する

    3. taskテーブル自体のread ACLが無いことを前提に、子テーブルごとの判定へ切り替える


    画像

    原因:taskテーブル自体にはread ACLが1件もありません。ACLが無いテーブルで何が起きるかは、システムプロパティが決めます。

    Security manager default behavior in the absence of any ACLs on a table

    (訳: テーブルにACLが一切無い場合の、セキュリティマネージャーの既定の振る舞い)

    引用元: /sys_properties_list.do?sysparm_query=name=glide.sm.default_mode


    画像

    この値はdenyでした。task.listに並ぶ行は1行ずつ、その行が実際に属するテーブルのACLで判定されます。sys_class_name=incidentの行はincident自身のread ACLで、sys_class_name=problemの行はproblem自身のread ACLで判定されます。どの子テーブルにも分類されない素のtaskクラスレコードだけは、キャッチオールACL経由でadmin以外は読めません。

    対処:「空に見える」なら、対象ユーザーが各プロセスの読み取りロールを持っているかを子テーブルごとに確認します。「全部見える」なら、adminロールでログインしていないか、あるいはキャッチオールACLの条件を確認します。詳しい判定構造は、本シリーズ第3巻「タスク管理モジュールのロール」が正本です。

    task直接のACLに残っているreport_view3件も見落としやすい部分です。ダッシュボードやレポートだけtaskを横断参照している場合、一覧では見えるのにレポートには出ないという逆方向の症状も起こり得ます。

    参考:Access Analyzer:「見えない」の理由を層で切り分ける … 層ごとに判定を追う道具

    保存が全プロセスで遅い・同じ挙動が起きる

    症状:Incident・Problem・Changeのどれを保存しても、同じように遅くなった、あるいは同じ挙動(例: 担当グループを変えると回数が加算される)が同時に出るようになりました。

    切り分け

    1. 遅さや挙動の変化が1プロセスだけか、複数プロセスに共通かを確認する

    2. 複数プロセス共通なら、task直接のBusinessRuleのorderを確認する

    3. 1プロセスだけなら、そのテーブル固有のBusinessRuleを疑う(本記事の対象外)

    原因:task直接のBusinessRuleはアクティブ33件あります。保存のたびに、63の子テーブルすべてでこの層が実行対象になります。


    画像

    代表例として、Task Active State Management(before・order50)はstateが変化するたびに動き、activeフィールドを自動更新します。reassignment counter(before・order100)はassignment_groupが変わるたびにreassignment_countを1件加算します。33件のうち条件なしで動くものは、全プロセス共通の処理です。async(非推奨)のものも5件あり、こちらは保存直後ではなく非同期のワーカーで実行されるため、遅延の体感がさらに読みにくくなります。

    対処:複数プロセス共通の遅さや挙動なら、この33件の中で条件式が緩いもの(無条件のもの)を最初に疑います。判断の材料になるのは、条件式とスクリプトの中身です。詳しい実行順序とTaskStateUtilの中身は、本シリーズ第5巻「タスク管理モジュールの自動設定構成」にまとめています。1件を実際に保存して発火数を数える実測は、Problemを対象にした記事で扱っています。

    参考:ServiceNowの保存で実際に動くBusiness Ruleは何本か? problemテーブルで定義と実測を比べる … 発火数の実測方法

    複製で意図しない項目までコピーされる

    症状:Change Taskで関連リストを複製すると、CIやサービスオファリングまで一緒にコピーされます。Problemで同じ操作をしても、そうした複製は起きません。

    切り分け

    1. 複製の挙動が違うのはどのプロセス間かを特定する

    2. その2プロセスそれぞれで、com.snc.<process>.copy.rl.*という名前のプロパティがあるかを確認する

    3. プロパティが無いプロセスでは、標準機能としての複製設定自体が用意されていない

    原因:関連リストの複製設定はプロセスごとに個別のプロパティで持たれています。taskレベルで共通化されておらず、あるプロセスには用意され、別のプロセスには無いという非対称が生じます。


    画像

    Changeの複製・連携設定は8件、Incidentは6件、Problemは0件でした。


    画像

    対処:ChangeとIncidentでは、対象プロパティの値(コピーする項目名のリスト)を編集すれば挙動を調整できます。Problemには同じ複製の仕組み自体がありません。同じ動きをさせたいなら、BusinessRule等での個別実装が必要になります。「他プロセスにあるはずの設定」を探し続けて時間を使わないよう、まず該当プロパティの有無を確認します。棚卸しをするときは、com.snc.change_request.copy.rl.*とcom.snc.incident.copy.rl.*を一覧にし、Problem側で不足している項目を洗い出す作業から始めると効率的です。

    継承で作った新テーブルでボタンや必須が出ない・出過ぎる

    症状:taskを継承して新しい業務テーブルを作ったところ、assignment_groupが常に必須になってしまいました。一方で、期待していたUIアクションのボタンは出ません。

    切り分け

    1. 「出過ぎる」項目は、task直接のUIポリシー・データポリシーが条件なしで効いていないかを確認する

    2. 「出ない」ボタンは、そのUIアクションの条件式が対象テーブルを名指しで絞り込んでいないかを確認する

    3. どちらも辞書上書き(sys_dictionary_override)の設定漏れが背景にないかをあわせて見る

    原因:taskのUIポリシーは1件だけで、条件なしのon_loadです。


    画像

    Make assignment group mandatoryという名前で、assignment_groupを無条件で必須にします。対象は63の直接の子テーブルすべてのフォームで、条件を問いません。新テーブルを作った時点で、このUIポリシーは自動的に対象へ含まれます。データポリシー(sys_data_policy2)はtask直接では0件のため、必須の制御はUIポリシーとACLだけに集中している点も、あわせて覚えておくと役立ちます。

    一方、UIアクションは26件あり、約半数はgetRecordClassName()等で対象テーブルを絞り込む条件を内部に持ちます。


    画像

    Create Outageはincidentとproblemだけに条件で限定されています。Verify Proposed Changesはchange_requestとchange_taskだけです。table=taskで定義されていても、新テーブルには対象名が無いため表示されません。


    画像


    画像

    対処:必須が出過ぎる場合は、taskのUIポリシーを個別テーブルで上書きします。子テーブル側に、対象を除外する新しいUIポリシーを追加する形です。ボタンが出ない場合は、該当UIアクションの条件式に新テーブル名を追加登録するか、新規のUIアクションを作成します。63テーブルという広い範囲に対する変更のため、影響確認は本番投入前に必ず行います。新しい業務テーブルの設計手順は、本シリーズ第9巻「タスク管理モジュールの開発設計書」で扱う予定です。

    参考:ServiceNowのResolveボタンはどこで動く? UI Actionの表示条件とClient/Server処理 … 条件式の読み方

    参考:辞書オーバーライド:継承フィールドを子だけ上書き … 上書きの仕組みそのものの解説

    新テーブルにSLAが付かない

    症状:taskを継承して新しい業務テーブルを作り、SLAを設定したいのに、継承しただけではタイマーが動きません。

    切り分け

    1. そのテーブル用のSLA定義(contract_sla)が存在するかを確認する

    2. task_slaがtaskの子テーブルだと誤解していないかを確認する

    3. 既存のSLA定義を新テーブル向けに複製・作成する必要がないかを判断する

    原因:SLAの計測結果を記録するtask_slaは、super_classが空でtaskの子テーブルではなく、taskとcontract_slaの両方を参照する橋渡しテーブルです。


    画像

    taskを継承しただけでは、task_slaのレコードは自動生成されません。生成の条件を握るのはSLA定義(contract_sla)です。taskレベルでのSLA定義は0件でした。


    画像


    画像

    対処:新テーブルにSLAを付けるには、そのテーブル用のcontract_slaレコードを新規作成します。collectionにテーブル名を指定し、開始・一時停止・停止の条件式を設定して初めてtask_slaが生成されます。既存プロセスのSLA定義を複製し、条件式だけを差し替える方法が近道です。応答SLAと解決SLAのように複数の時計を並走させたいなら、contract_slaも段階の数だけ用意します。1件のtaskに複数のtask_slaが同時に紐づく構造は、既存プロセスと同じです。

    参考:task_sla:1タスク1本のSLA時計の読み方 … 計測側のテーブル

    参考:SLA Definition(contract_sla)とは:時計を生むルール … 時計を生む条件設定

    実機で気づいたこと

    同じ状態遷移で、共通BRと個別BRが二重に書き込む

    task直接のBusinessRule「Task Active State Management」(order50)は、stateがcloseStatesに入る値へ変わるたびにactiveをfalseにします。Incidentには同じ動きをする固有のmark_closed(order100)も別に存在します。Incidentをクローズすると、order50とorder100の両方がactiveへfalseを書き込む形です。

    2つの独立した条件(task共通はstateの値、Incident固有はincident_stateの値)が、同じ結論に達する構成です。2回目の書き込みは同じ値の再代入なので、実害はありません。ただし責務は重複しています。

    保存1回で発火するBusinessRuleの数を数えるとき、この重複を不具合と早合点しないでください。task直接BRのorder800(mark closed)は、runMarkClosed()のignoreTablesでincidentとproblemを除外しており、この2テーブルでは動きません。動くテーブルと動かないテーブルが混在する点もあわせて確認します。

    ignoreTablesの中身は関数ごとに違う

    TaskStateUtilの3つの関数は、それぞれ別のignoreTablesを持ちます。mark closedを動かすrunMarkClosed()はproblemとincidentの2件、task closerを動かすrunTaskCloser()はsn_hr_core_taskの1件、task reopenerを動かすrunTaskReopener()は0件(除外なし)です。

    「incidentとproblemはtask共通の処理から除外されている」という理解を、クローズ処理以外にも当てはめると外れます。再オープンの処理は、incidentとproblemも含めた全テーブルが対象です。

    新しいtask継承テーブルで状態遷移が想定通り動かないときは、どの関数のignoreTablesを見ているかを先に確認します。1つの関数で除外を確認しても、別の関数では除外されていない場合があります。

    task共通の通知定義は、実際には1テーブルしか発火しない

    collection=taskの通知定義は1件だけです。対象範囲は63テーブル全体のはずですが、実際にイベントを発行するBusinessRuleを追うと、collection=vtb_task専用の1本だけがイベントをキューに積んでいました。

    通知定義の対象範囲と、実際にイベントを発行する側の範囲が一致していません。定義だけを見て「task継承テーブルなら届くはず」と考えると外れます。

    新しいtask継承テーブルで通知が届かないときは、通知定義の有無だけでなく、そのイベント名をeventQueueしているBusinessRuleがどのcollectionに絞られているかまで確認します。

    実務で順番に検討する箇所

    複数プロセスで同時に同じ症状が出たときは、次の順序で確認します。原因の層を最初に絞り込めれば、子テーブル側の設定を無駄に調べ直す時間を減らせます。

    1. 症状の範囲を確認:1プロセスだけか、複数プロセスで同時に起きているかを最初に切り分ける

    2. task直接のACLを確認:全プロセスで編集できないなら、task.*のフィールドACLとロールを見る

    3. task直接のBusinessRuleを確認:全プロセスで同じ遅さ・同じ挙動が出るなら、共通BR33件のorderを見る

    4. プロパティのプロセス別非対称を確認:複製やコピーの挙動がプロセスごとに違うなら、copy.rl系プロパティの有無を見る

    5. 辞書上書きとUIポリシー・UIアクションを確認:継承直後のテーブルでボタンや必須が想定と違うなら、条件の有無を見る

    6. SLA定義の有無を確認:新テーブルにSLAが付かないなら、そのテーブル用のcontract_slaを作成したかを見る


    画像

    これらの確認は、いずれも本シリーズの該当する巻で詳しく扱っています。1つずつ潰していくと、原因の層を見誤りません。

    用語

    • OOTB:Out of the Box。プラグイン追加やカスタマイズを行っていない、製品のデフォルト状態

    • PDI:Personal Developer Instance。ServiceNowが無償で提供する個人検証用インスタンス

    • task_editor:「保護されたtaskフィールドを編集できる」という単一機能のロール

    • 辞書上書き(Dictionary Override):sys_dictionary_override。継承した項目の設定を子テーブルだけで変更する仕組み

    • TaskStateUtil:task共通の状態遷移処理を行うサーバ側の共通クラス

    • contract_sla:SLA定義そのものを保持するテーブル。task直接では0件で、各プロセスが個別に持つ

    • ignoreTables:TaskStateUtilの各関数が処理対象から除外するテーブル名の配列。関数ごとに中身が異なる

    検証範囲とおことわり

    • 検証環境:Australia PDI / OOTB / 2026-09-01 確認

    • 件数と条件式はすべてOOTBの定義に基づきます。本番環境やカスタマイズ済み環境では異なります

    • 本記事で扱った実測値の多くは、本シリーズの既刊各巻(第2〜4巻・第5巻)で確定した値の引用です。数値の再測定は行っていません

    • 各症状を実際に再現し、対処して直ることまでは確認していません。定義と条件式から原因を整理しています

    • 新しいtask継承テーブルを実際に作成して検証する操作は行っていません

    • BusinessRule33件全件・UIアクション26件全件のスクリプト精読はしていません。代表例のみを確認しています

    • ドメイン分離を有効化した環境での挙動(ドメインによる絞り込みがACL判定より前に入る点)は、本記事の対象外です

    付録:自分の環境で確認するときのURL

    • task.フィールドACL:/sys_security_acl_list.do?sysparm_query=nameSTARTSWITHtask.^active=true

    • 既定動作のプロパティ:/sys_properties_list.do?sysparm_query=name=glide.sm.default_mode

    • task直接のBusinessRule:/sys_script_list.do?sysparm_query=collection=task^active=true^ORDERBYorder

    • 複製設定のプロパティ:/sys_properties_list.do?sysparm_query=nameLIKEcopy.rl

    • task直接のUIポリシー:/sys_ui_policy_list.do?sysparm_query=table=task^active=true

    • task直接のUIアクション:/sys_ui_action_list.do?sysparm_query=table=task^active=true

    • SLA定義(task直接):/contract_sla_list.do?sysparm_query=collection=task

    • task_slaのフィールド一覧:/sys_dictionary_list.do?sysparm_query=name=task_sla^elementISNOTEMPTY

    引用した公式説明を実機で確認する方法

    この記事で引用した説明文は、ServiceNowが製品に同梱しているプロパティのドキュメントです。次のURLを自分のインスタンスで開くと、同じ記述が見つかります。

    • プロパティの公式説明(引用元):/sys_properties_list.do?sysparm_query=name=glide.sm.default_mode

    関連記事

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

    あなたへのおすすめ