Extended Table レコードを更新してクラスを変更した場合に何が発生するかIssue <!-- /*NS Branding Styles*/ --> .ns-kb-css-body-editor-container { p { font-size: 12pt; font-family: Lato; color: var(--now-color--text-primary, #000000); } span { font-size: 12pt; font-family: Lato; color: var(--now-color--text-primary, #000000); } h2 { font-size: 24pt; font-family: Lato; color: var(--now-color--text-primary, black); } h3 { font-size: 18pt; font-family: Lato; color: var(--now-color--text-primary, black); } h4 { font-size: 14pt; font-family: Lato; color: var(--now-color--text-primary, black); } a { font-size: 12pt; font-family: Lato; color: var(--now-color--link-primary, #00718F); } a:hover { font-size: 12pt; color: var(--now-color--link-primary, #024F69); } a:target { font-size: 12pt; color: var(--now-color--link-primary, #032D42); } a:visited { font-size: 12pt; color: var(--now-color--link-primary, #00718f); } ul { font-size: 12pt; font-family: Lato; } li { font-size: 12pt; font-family: Lato; } img { display: ; max-width: ; width: ; height: ; } } この記事は、Extended Tableレコードの Class/Task Type [sys_class_name] フィールドが更新され、Extended Table階層内の別のテーブルへレコードを移動する際に何が発生するかを説明し、デバッグを支援し、潜在的な問題を回避することを目的としています。 CMDB の観点では、これは CI の再分類(Reclassifying a CI)と呼ばれ、レコードを階層内のどこへ移動するかによって、クラスはアップグレード、ダウングレード、または切り替えされます。 インスタンス内には 100 を超えるExtended Tableと、1000 を超える子テーブルがあります。Extension Models を理解すると、このフィールド値を変更することは、実質的にレコードをあるテーブルから別のテーブルへ移動することになると理解できます。 Release<!-- /*NS Branding Styles*/ --> .ns-kb-css-body-editor-container { p { font-size: 12pt; font-family: Lato; color: var(--now-color--text-primary, #000000); } span { font-size: 12pt; font-family: Lato; color: var(--now-color--text-primary, #000000); } h2 { font-size: 24pt; font-family: Lato; color: var(--now-color--text-primary, black); } h3 { font-size: 18pt; font-family: Lato; color: var(--now-color--text-primary, black); } h4 { font-size: 14pt; font-family: Lato; color: var(--now-color--text-primary, black); } a { font-size: 12pt; font-family: Lato; color: var(--now-color--link-primary, #00718F); } a:hover { font-size: 12pt; color: var(--now-color--link-primary, #024F69); } a:target { font-size: 12pt; color: var(--now-color--link-primary, #032D42); } a:visited { font-size: 12pt; color: var(--now-color--link-primary, #00718f); } ul { font-size: 12pt; font-family: Lato; } li { font-size: 12pt; font-family: Lato; } img { display: ; max-width: ; width: ; height: ; } } すべて Cause<!-- /*NS Branding Styles*/ --> .ns-kb-css-body-editor-container { p { font-size: 12pt; font-family: Lato; color: var(--now-color--text-primary, #000000); } span { font-size: 12pt; font-family: Lato; color: var(--now-color--text-primary, #000000); } h2 { font-size: 24pt; font-family: Lato; color: var(--now-color--text-primary, black); } h3 { font-size: 18pt; font-family: Lato; color: var(--now-color--text-primary, black); } h4 { font-size: 14pt; font-family: Lato; color: var(--now-color--text-primary, black); } a { font-size: 12pt; font-family: Lato; color: var(--now-color--link-primary, #00718F); } a:hover { font-size: 12pt; color: var(--now-color--link-primary, #024F69); } a:target { font-size: 12pt; color: var(--now-color--link-primary, #032D42); } a:visited { font-size: 12pt; color: var(--now-color--link-primary, #00718f); } ul { font-size: 12pt; font-family: Lato; } li { font-size: 12pt; font-family: Lato; } img { display: ; max-width: ; width: ; height: ; } } 一般的に、既存のレコードが新しい Class 値で更新された場合、次の手順が実行されます。 インスタンス内のユーザーまたはスクリプトが既存のレコードを更新します。sys_class_name 値が変更され、さらに他のフィールドも変更される可能性があります。以前のクラスに対して Before Update Business Rule が実行されます。before 1000 の Engine も実行されます。Async および After Business Rule は実行されません。GlideRecordClassSwitcher switchClass() が実行されます。 いくつかのチェックを実行します。"Change in class detected, switching from: <previous.sys_class_name> to: <current.sys_class_name> sys_id: <sys_id>" をログに記録します。通貨フィールド値などの複数値フィールドに対する外部レコードを更新します。すべてのレコード値をメモリに読み込みます。Business Rule などを実行せずに、以前のクラステーブルからレコードを削除します。元のレコードのすべての値を使用して新しいレコードを挿入します。Business Rule などは実行しません。古いレコードに添付ファイルがある場合、新しいレコードへ割り当てます。新しく挿入されたレコードを更新します(これは最初の更新に加えて実行されます)。 新しいクラスに対して Before Update Business Rule を実行します。更新を監査します。新しいクラスに対して After Update Business Rule を実行します。 Resolution<!-- /*NS Branding Styles*/ --> .ns-kb-css-body-editor-container { p { font-size: 12pt; font-family: Lato; color: var(--now-color--text-primary, #000000); } span { font-size: 12pt; font-family: Lato; color: var(--now-color--text-primary, #000000); } h2 { font-size: 24pt; font-family: Lato; color: var(--now-color--text-primary, black); } h3 { font-size: 18pt; font-family: Lato; color: var(--now-color--text-primary, black); } h4 { font-size: 14pt; font-family: Lato; color: var(--now-color--text-primary, black); } a { font-size: 12pt; font-family: Lato; color: var(--now-color--link-primary, #00718F); } a:hover { font-size: 12pt; color: var(--now-color--link-primary, #024F69); } a:target { font-size: 12pt; color: var(--now-color--link-primary, #032D42); } a:visited { font-size: 12pt; color: var(--now-color--link-primary, #00718f); } ul { font-size: 12pt; font-family: Lato; } li { font-size: 12pt; font-family: Lato; } img { display: ; max-width: ; width: ; height: ; } } このプロセスを考慮すると、次のことが起きる理由を説明できます。 目次 Before Business Rule が 2 回実行される.setWorkflow(false) は Business Rule や Audit の実行を防止しない.autoSysFields(false) は Updated / Updated By などの更新を防止しないAfter Business Rule の "Class Changes" フィルター条件はトリガーされないデータ損失 - 新しいクラスにフィールドが存在しないデータ損失 - Insert が失敗した場合、レコードが削除される可能性があるレコードごとに長時間かかる場合があるClass 変更前の Audit レコードが存在しないように見えるCSDMLifeCycleSyncScriptEngine が Insert 前に実行され、Life Cycle Stage/State の値を変更する可能性がある Before Business Rule が 2 回実行される ユーザーまたはスクリプトによる最初の更新 ソーステーブルの Before Update Business Rule クラス変更コードによる追加更新 ターゲットテーブルの Before Update Business Ruleターゲットテーブルの After Update Business Ruleターゲットテーブルの Async Update Business Rule .setWorkflow(false) は Business Rule や Audit の実行を防止しない このメソッドは、「後続の操作によって通常トリガーされる Business Rule の実行を有効または無効にします。パラメータ e が false に設定されている場合、insert/update は監査されません。Audit は GlideRecord 操作でパラメータが true の場合にのみ行われます。」という動作をします。 スクリプトから Class 変更を実行し、.update() の前に setWorkflow(false) を使用した場合、ソーステーブルの Before Update Business Rule の実行のみを防止します。 これは、新しいレコードの挿入後にクラス変更コードが実行する追加の Update() には影響しません。ターゲットテーブルの Before Business RuleAfter Business RuleAsync Business Rule は引き続き実行されます。これを防止する方法はありません。 大量レコードをバッチ更新する場合は、Session Debug などを使用して実行される Business Rule を分析し、長時間実行されるものや問題を引き起こす可能性のある Business Rule を一時的に無効化することを検討してください。 .autoSysFields(false) は Updated / Updated By などの更新を防止しない この関数は、「sys_updated_by、sys_updated_on、sys_mod_count、sys_created_by、および sys_created_on フィールドの更新を有効または無効にします。これは、履歴情報を変更せずにレコードのフィールド値を手動で更新する場合によく使用されます。 setWorkflow(false) と同様に、これは最初の更新にのみ適用されます。後続の Insert および Update により、新しい値が設定されます。結果として: sys_created_on は実行時刻になります。sys_mod_count は 0 に戻ります。 After Business Rule の "Class Changes" フィルター条件はトリガーされない After Update Business Rule が実行される時点では、その更新は実質的に insert として処理され、クラスは変更されていません。そのため、フィルター条件(Filter Conditions)が意図通りに機能しない(条件に合致しないと判断される)ことがあります。しかし、条件をスクリプトで記述すれば、ルールをトリガーさせることが可能です。 Condition: current.sys_class_name.changes(); データ損失 - 新しいクラスにフィールドが存在しない 元のクラスに存在していたフィールドが新しいクラスに存在しない場合、それらの値は失われます。 例: cmdb_ci_win_server から cmdb_ci_ip_switch へ再分類すると、以下のようなフィールド値が失われます。 cpu_namehost_name データ損失 - Insert が失敗した場合、レコードが削除される可能性がある 前述のとおり、このレコードは最初にソーステーブルから削除され、その後ターゲットテーブルに挿入されます。削除がすでに実行された後に、さまざまな要因によって Insert が実行されない可能性があり、その結果、レコードが失われます。 主な要因: Insert が実行される前に、トランザクションがタイムアウトするか、またはユーザーによってキャンセルされる可能性があります。この現象は Jakarta 以降でより頻繁に確認されましたが、それ以前のバージョンでも発生する可能性がありました。 London 以降のバージョンでは、これを防ぐ必要があります。「KB0727782:PRB1242353 UI から多くの CI のクラスを変更すると、トランザクションがキャンセルされ、いくつかのレコードが削除される可能性がある」を参照してください。 必須フィールドルールを持つ Data Policy によって、Insert が防止される可能性があります。これは既知の製品不具合です。 「KB0727701:PRB631444 レコードの sys_class_name を変更する場合、必須フィールドのデータポリシーによりターゲットテーブルへの挿入ができないと、レコードが削除される可能性がある」を参照してください。 レコードごとに長時間かかる場合がある 単一レコードのクラス変更は数秒で完了する場合もありますが、実行に数分かかる場合もあります。その原因は Business Rule の実行である可能性があり、Session Debug によって調査対象を特定できます。 Jakarta(TPP が使用されていた時期)および Kingston では、データベースログを分析すると、多くの時間が Delete ステップ中の Dictionary および関連テーブルに対する大量のクエリ実行に費やされていることが通常確認されます。これは、このモデルで使用される追加の Dictionary レコードが多数存在するためです。 これは London 以降で KB0681177: PRB1258222 Unnecessary updates during cmdb_ci class change from TPP change によって改善されています。 Class 変更前の Audit レコードが存在しないように見える Audit レコードは、その時点のテーブル名で記録されます。Class 変更前に作成された sys_audit レコードは、新しいテーブル名へ更新されません。History Set および History Line を生成するコードは、この状況を考慮しています。 そのため、以下の機能は通常動作します。 History ListActivity FormatterCMDB TimelineCMDB Baseline Diff ただし、新しいテーブル名で直接 sys_audit を検索した場合、変更後の履歴しか表示されません。この場合は document_key(sys_id)を使用してください。 また、旧クラスまたは新クラスのテーブルが Dictionary で Audit 有効になっていない場合、完全な監査履歴を期待することもできません。 CSDMLifeCycleSyncScriptEngine が Insert 前に実行され、Life Cycle Stage/State の値を変更する可能性がある CMDB テーブルでは、Insert 前に動作する Script Engine が存在し、従来の Status フィールド値に基づいて以下を自動設定できます。 life_cycle_stagelife_cycle_stage_status Class 変更は実際には Delete + Insert として実行されるため、この処理は Class 更新時にも実行されます。 ProductInstance 2.0 がまだ有効になっていない場合、以下のフィールドと現在の Life Cycle 状態が一致しないと、 install_statusoperational_status life_cycle_mapping および life_cycle_control に定義されたマッピングに基づいて、 life_cycle_stagelife_cycle_stage_status の値が上書きされる可能性があります。