CMDBに仮想コンピューターまたはサーバーCIを挿入する際に発生する「Duplicate entry for key 'PRIMARY'」エラーの解決方法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: ; } } CMDBにコンピューターまたはサーバーCIを挿入する際に発生するSQLレベルの「Duplicate entry for key 'PRIMARY'」エラーを解決します。このエラーは挿入の失敗を引き起こし、関連するコードが予期しない動作をする原因となります。 CMDBにコンピューターまたはサーバーCIを挿入する際、手動、ディスカバリーツール、またはインポートのいずれの方法を使用した場合でも、そのCIが既に挿入されていることを示す以下のSQLエラーが表示されることがあります。 例: FAILED TRYING TO EXECUTE ON CONNECTION nn: INSERT INTO cmdb (`a_str_5`, `a_int_8`, `skip_sync`, `operational_status.... java.sql.BatchUpdateException: Duplicate entry '7caaf9c31b9dff846825a64fad4bcb6a' for key 'PRIMARY' : java.sql.SQLException: java.sql.BatchUpdateException: Duplicate entry '7caaf9c31b9dff846825a64fad4bcb6a' for key 'PRIMARY': com.glide.db.StatementBatcher.getSQLException(StatementBatcher.java:469) 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: ; } } CI関係レコードの挿入時に実行されているカスタムビジネスルールが、親CIがデータベースに存在する前にその親CIに対して .update() を呼び出しています。これにより、プラットフォームが親CIを早期挿入し、その後、実際の挿入トランザクションが重複キーエラーで失敗します。 挿入されるCIがコンピューター CI [cmdb_ci_computer]、サーバー、またはコンピューターを拡張するクラスである場合に、この問題が発生する流れを以下に示します。 IsVirtual フラグを挿入前に設定する必要があるため、ベースシステムの Virtual Computer Check ビジネスルールがコンピューター CI の挿入前に実行されます。このルールによってVMインスタンスレコードが見つかった場合、そのCIが仮想であると識別され、VMとインスタンスの間に「instantiates」関係レコードが挿入されます。関係レコード [cmdb_rel_ci] が挿入されます。関係レコード [cmdb_rel_ci] のすべての挿入ビジネスルールが、この挿入の一部として実行されます。ステップ3のカスタムビジネスルールが関係の親に対して .update() を呼び出すと、プラットフォームは親コンピューター CI をデータベースに早期挿入します。これは、まだ存在しないレコードに対して .update() を呼び出すと、プラットフォームがそのレコードを挿入するためです。残りの関係レコード挿入ビジネスルールが完了します。残りのコンピューター CI 挿入前ビジネスルールが完了します。プラットフォームは元のトランザクションの一部としてコンピューター CI の挿入を試みますが、ステップ4でそのCIが既に挿入されているため、重複キーエラーが発生して失敗します。 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: ; } } カスタムビジネスルールは、まだ挿入されていないCIに対して .update() を呼び出さないように再設計する必要があります。以下の原則が適用されます。 関係レコード [cmdb_rel_ci] が挿入される時点で、親CIと子CIの両方が存在すると想定しないでください。ベースシステムの Virtual Computer Check ビジネスルールは、親CIが存在する前に関係を挿入できるコードの一例です。他のプラットフォームプロセスも同様に動作する可能性があります。存在しないレコードに対して .update() を呼び出すと、プラットフォームがそのレコードを早期挿入します。その後、元の挿入を実行しようとするコードは重複キーエラーで失敗します。カスタムビジネスルールのロジックを見直し、関係レコードの挿入中に親CIに対して .update() を呼び出さないようにしてください。遅延処理の使用を検討するか、.update() を呼び出す前にCIが既に存在するかどうかを確認してください。 Related Links<!-- /*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: ; } } 本記事で説明している動作は、GlideRecord の仕様による動作と一致しています。存在しないレコードに対して .get() を呼び出すと、プラットフォームはメモリ上に新しい GlideRecord を初期化します。スクリプトで参照フィールドをドットウォークして参照レコードオブジェクトを取得する場合も同様です。その後、そのインメモリレコードに .update() を呼び出すと、プラットフォームがそのレコードを挿入します。 この動作は、GlideRecord サーバーAPIリファレンスの .update() に記載されています。 "Updates the GlideRecord with any changes that have been made. If the record does not exist, it is inserted." 詳細については、ServiceNow 開発者ドキュメントの GlideRecord documentationを参照してください。