Skip to content

載入期間的自動化

另有 19 種語言版本

English · Español · 日本語 · Português (Brasil) · Français · Deutsch · Italiano · 한국어 · 简体中文 · Português (Portugal) · Bahasa Indonesia · Türkçe · Polski · Tiếng Việt · ไทย · Українська · Español (México) · Français (Canada) · Deutsch (Schweiz)

In a plant room, the valves beside a pump stand closed and its cover is off, while a bypass pipe with an open valve carries the flow around it.
圖片由 AI 生成

第 3 個模組,共 5 個,屬於 Data Architect 課程第 10 章遷移與同步。每個模組都可以單獨閱讀。 上一篇:大數據量載入 · 下一篇:切換週末

**本模組回答的問題:**在載入遷移資料期間,Salesforce 的自動化應該怎麼處理?

RouteDesk’s records are ready: about 707,000 of them, prepared, sorted by parent, rehearsed. You start the load, and Salesforce starts doing exactly what you configured it to do. Flows fire, triggers run, validation rules evaluate, emails send, tasks get created, rollups calculate, integrations launch, events publish. Your 707,000-record migration isn’t performing 707,000 operations anymore. It’s performing 707,000 records multiplied by everything each record causes. That’s a different migration. ⟲

Here’s the landscape again, the weekend RouteDesk retires. The migration arrow is amber. Now look at what else leaves Salesforce when a Work Order is created or changes status. ⟲

The arrows a load sets off Steve Trucking's landscape from Checkpoint 1, in the same places, the weekend RouteDesk retires. The migration arrow from RouteDesk into Salesforce is in amber. Three arrows leaving Salesforce are red with an X, because normal automation would fire them for every migrated Work Order: status events to the integration layer, delivery counts to the integration layer, and the day-before texts to the SMS and email provider. Underneath: load 196,400 Work Orders with the automation on, and three more arrows fire for every one of them: status events, delivery counts and day-before texts. {"author": "Steve Simpson", "blueprint": "1.0.1", "builder": "standard 1.54.0", "built": "2026-10-30", "id": "DGM-DA-MG-30", "rights": "\u00a9 2026 Twinshark LLC. All rights reserved.", "template": "system-landscape 0.13.0", "theme": "stevetecharc 1.4.0"} ABOVE: IDENTITY, APPEXCHANGE, WEB PEOPLE RIGHT: INTERNAL SYSTEMS BELOW: CUSTOMER CHANNELS BOTTOM RIGHT: PARTNERS AND PROVIDERS Dispatch coordinators 45, inside 9 partner DCs Delivery crews ~700 on 330 trucks Care and office staff 100: service, ops, finance Retail Partner users ~300 at 3 partners Recipients ~1 million a year Corporate IdP SSO for office staff only Retail Partner portal Tracking page INTEGRATION Snowflake status history, analytics FleetLink raw GPS stays here Finance ERP invoices partners, pays crews Photo storage 4–5 million a year, off core RouteDesk retiring: 8 years, ~5 million deliveries Phone care agents Email email-to-case SMS and email provider day-before message, with a link Redrock REST API, webhooks Keystone CSV over SFTP Brightwave EDI through a third-party network Salesforce Field Service, one US org a link, no login office staff only calls cases in manifests in status out manifests in status out manifests in status out upserts, partner key status events status events latest position only delivery counts delivery counts photos, from the crews' app day-before, with a link what's still open: migrated once Salesforce a community people identity, apps, web an internal system a customer channel the integration layer starts at the system that opens the connection; the label says what moves red with an X: fires for every migrated record unless you decide otherwise a shared certificate: trust, no direct call the migration Load 196,400 Work Orders with the automation on, and three more arrows fire for every one of them: status events, delivery counts and day-before texts. © 2026 Twinshark LLC · stevetecharc.com
點擊放大

One arrow in. Three more arrows out, for every record, unless we decide otherwise. ⟲

Every one of those arrows was designed in chapter 9 for a delivery that just happened: a status changed, so tell the partner and Snowflake; a delivery finished, so count it for invoicing; a delivery is tomorrow, so text the Recipient. The load creates 196,400 Work Orders in one weekend, and about 190,000 of them arrive already completed. To the automation, each one looks like a delivery that just happened. ⟲

Salesforce sees a record transaction. It doesn’t know “this is historical data loaded during a controlled cutover.” A flow sees a new Account and does what it was built to do: creates an onboarding task, sends a welcome email, publishes an event, updates a related record, calls another system. Correct when a sales rep creates one account on Tuesday afternoon. Completely wrong when a migration creates 800,000 historical accounts on Saturday night. Same operation, different business context. At Steve Trucking, a Work Order arriving with a status of Completed looks exactly like a crew finishing a delivery five minutes ago. ⟲

所以對於一次大型遷移,我的出發點是:正常的業務自動化**不應該盲目地針對載入執行。**這不是說「關掉一切」。而是說每一個重要的自動化都要有一個有意識的決定,而我不想等到生產環境發出了 400,000 封郵件才發現答案。

三種選擇:不需要它、模擬它、推遲它

Section titled “三種選擇:不需要它、模擬它、推遲它 ”

For each automation, I ask what it does and what happens if it doesn’t run, and then I put it in one of three categories. ⟲

**不需要它(消除)。**對於遷移過來的記錄,這個行為就不應該發生。我們已經合作了八年的客戶,不需要「歡迎加入我們公司!」插入一個客戶,它就發一封郵件;載入一百萬個客戶,我可不需要一百萬封郵件。

**模擬它。自動化不應該執行,但它產生的結果依然是必需的。**一個在建立客戶時執行的 flow 會推算出客戶細分(Customer Segment)。遷移過來的客戶需要一個有效的細分,但把整個 flow 執行五百萬次代價太高,或者有副作用。所以我們在轉換中計算出細分,把結果載入進去。我們沒有忽視業務規則;我們在載入中完成了自動化的工作。

**推遲它。**結果是需要的,但不必在載入事務之內。關掉自動化、設定一個標誌進行載入,然後觸發一個批次處理來補上:重新計算,建立依賴記錄,釋出下游系統需要的東西。推遲可以讓載入更快、更可控,而不放棄結果。

有時你也會讓它開著。對於一次較小的載入,如果業務希望它的正常流程執行,就讓系統做它該做的事。那也是一種選擇,只要它確實是一種選擇。

無論你選哪一種,這是我教的規則:**每當你關掉一個自動化,你就要為那段業務邏輯沒有執行承擔全部責任。**在做決定之前,你需要理解每一個自動化。

Don't need it, simulate it, defer it A decision tree, read left to right, with three questions and four answers. First question: should it happen for migrated data? If no: don't need it, for example status messages to partners for deliveries they closed weeks ago. If yes, the second question: must it happen inside the load? If yes: let it run, deliberately, for example the rule that every Work Order has a partner. If no, the third question: can the preparation set the result, a value rather than a side effect? If yes: simulate it, for example the Work Order's status, mapped in the preparation data store. If no: defer it, for example status history to Snowflake, as one backfill after the load. Underneath, Steve's rule: any time you turn an automation off, you're taking full responsibility for that business logic not happening. {"author": "Steve Simpson", "blueprint": "1.0.0", "builder": "standard 1.48.0", "built": "2026-10-27", "id": "DGM-DA-MG-31", "rights": "\u00a9 2026 Twinshark LLC. All rights reserved.", "template": "cells 0.4.0", "theme": "stevetecharc 1.4.0"} THE QUESTIONS THE ANSWERS Should it happen for migrated data? ask it of every automation Must it happen inside the load? or can it come later Can the preparation set the result? a value, not a side effect Don't need it status messages to partners for deliveries closed weeks ago Let it run, deliberately the rule that every Work Order has a partner Simulate it the Work Order's status, mapped in the preparation data store Defer it status history to Snowflake: one backfill after the load no yes yes no yes no Any time you turn an automation off, you're taking full responsibility for that business logic not happening. © 2026 Twinshark LLC · stevetecharc.com
點擊放大

Three questions, four answers, one decision per automation. ⟲

Test knowledge. For each automation on a large load, decide: not needed for migrated data (bypass it), needed but its result can be set in the data (simulate it in the transformation), needed but not inside the load (defer it to a batch afterward), or needed inside the load (let it run). Expect a scenario where blindly running automation creates unwanted emails, tasks or integration calls, and one where turning it off silently loses a required result. ⟲

「停用自動化」不是完整的策略

Section titled “「停用自動化」不是完整的策略 ”

計劃上寫著「停用自動化」。哪個自動化?怎麼停,誰來停,什麼時候停?我們怎麼知道它關了,又怎麼知道它重新開了?它通常產生的哪些結果在之後仍然必須存在?如果它關著的時候使用者在系統裡,或者遷移進行到一半失敗了,會怎樣?關掉某樣東西是一個運維操作。架構需要完整的生命週期:正常狀態、遷移狀態、恢復正常,以及我們確實恢復了的證明。

And before you decide what to switch off, find out what’s still switched on. Old automation runs on migrated records too. Salesforce ended support for Workflow Rules and Process Builder on December 31, 2025, but “your active Workflow Rules and Process Builder processes continue to run as they did before” (工作流程規則和流程產生器終止支援 (在新標籤頁中開啟), Salesforce Help, checked 2026-10-27). Well-Architected points out the cost: an org “carrying dozens of Process Builders left over from prior implementations … pays to evaluate every one of them on every relevant record save,” and its advice is to “migrate remaining Process Builders to Flow; don’t just deactivate them” (Resource and Cost Optimization (在新標籤頁中開啟), checked 2026-10-27). A migration is a good reason to clear them out first, so 707,000 records aren’t run through automation nobody remembers. ⟲

我更強烈的立場是:**重要的自動化應該有一個受控的繞過機制,即使並沒有計劃遷移。**遷移不是你需要它的唯一理由。大規模的修復、資料更正、回填、整合修復、緊急恢復:有時你必須在沒有全部正常自動化的情況下執行一個受控的操作。如果唯一的辦法是在生產環境裡修改 flow、停用觸發器或刪除驗證規則,我們就讓運維工作變得毫無必要地危險。而且你不能簡單地在生產環境裡關掉一個觸發器:那是一次部署,還要帶上它的測試。

The standard answer is a bypass (some teams call it a kill switch): the first thing the trigger or flow does is check a switch, and skip itself if the switch is on. Decide the scope: a global switch for the whole org, one per object, one per automation, or one for particular users, such as the data load user or anyone holding a permission. Put it in your flows as well as your triggers. Flows are easy to deactivate, but a user-specific switch lets everyone else keep working. I consider flows visual programming: whether you’re writing code or programming visually, you’re still programming, and programs need this. ⟲

And here’s the part teams miss: the bypass is part of the original design. It isn’t something you build the week you need it. Every trigger and flow gets its bypass when it’s first built. It’s tested both ways, switched on and switched off, like any other behavior. And it goes to production with the automation, long before any migration, so on cutover weekend it’s already there, already tested, and ready to switch on. A bypass written in a hurry for the load is new, untested code going into production on the riskiest weekend of the project. Salesforce’s Record-Triggered Automation decision guide is just as firm: “A well-architected Salesforce organization requires a consistent and reliable mechanism to bypass automation. This is not an optional feature, but a core operational requirement” (Record-Triggered Automation (在新標籤頁中開啟), Salesforce Architects decision guide, checked 2026-10-27). ⟲

Salesforce says the same thing in its own words. Its Well-Architected list of automation anti-patterns includes “Flows must be manually deactivated prior to bulk data loads” (Automation Patterns (在新標籤頁中開啟), Operational Excellence, checked 2026-10-27). If your load plan says “deactivate these twelve flows on Friday night,” that’s the anti-pattern. ⟲

Test knowledge. Build a bypass into triggers and flows when they’re first built (a check of a custom permission, a custom setting or custom metadata at the start), test it on and off, and deploy it ahead of time, so large loads can skip them without editing or deactivating anything in production. Scope it: by object, by automation, or by user, such as the migration user. Deactivating flows by hand before a bulk load is an anti-pattern in Salesforce’s own Well-Architected guidance. ⟲

So what does a bypass actually look like? Three parts: a place to keep the switch, a check at the top of every trigger and flow, and the same check in the validation rules you decide to relax. Salesforce gives you three places to keep it, and each one decides who the switch applies to. ⟲

Where the switch livesWho it applies toGood for
A custom permission, granted by a permission setOnly the users who hold itThe usual migration bypass: give it to the migration user for the load, take it away after
A hierarchy custom settingThe whole org, one profile, or one userA global “automation off” for everyone, or a switch for one profile or one user
A custom metadata record per automationEveryone, for that one automationSwitching off one specific automation, deployed and versioned like code

The hierarchy custom setting is the one that does global, profile and user in one place. Salesforce’s description: it “checks the organization, profile, and user settings for the current user and returns the most specific, or lowest, value” (Define Custom Settings (在新標籤頁中開啟), Salesforce Help, checked 2026-10-27). Set it off for the org, on for the migration user, and the migration user gets the bypass while everyone else gets normal automation. For most other configuration Salesforce now steers you to custom metadata instead, which deploys with your code; I’d use that for the per-automation switches. ⟲

In Apex, the check is the first thing the trigger does. Here’s what it could look like on the Work Order, with a hierarchy custom setting called Automation_Bypass__c and a custom permission called Bypass_Automation: ⟲

trigger WorkOrderTrigger on WorkOrder (after insert, after update) {
// The hierarchy custom setting: the user's value, else the profile's, else the org's
Automation_Bypass__c settings = Automation_Bypass__c.getInstance();
// Bypass if the setting says so, or if this user holds the custom permission
Boolean bypass = settings.Disable_Triggers__c == true
|| FeatureManagement.checkPermission('Bypass_Automation');
if (bypass) {
return; // no side effects; the record still saves
}
WorkOrderStatusOut.publish(Trigger.new, Trigger.oldMap);
}

getInstance() returns the setting “for the current user,” merged from the lowest level that’s defined (Custom Settings Methods (在新標籤頁中開啟)), and FeatureManagement.checkPermission “checks whether a custom permission is enabled” (FeatureManagement Class (在新標籤頁中開啟); both Apex Reference Guide, Winter ‘27, checked 2026-10-27). ⟲

And one switch per automation, so the bypass is scoped instead of “skip everything.” A custom metadata type, Automation_Switch__mdt, with one record per automation: ⟲

public with sharing class WorkOrderStatusOut {
public static void publish(List<WorkOrder> orders, Map<Id, WorkOrder> oldOrders) {
// One record per automation; switched off here, it's off everywhere it's deployed
Automation_Switch__mdt sw = Automation_Switch__mdt.getInstance('WorkOrder_Status_Out');
if (sw != null && sw.Is_Off__c) {
return;
}
// ... publish the status change for the partners
}
}

getInstance(developerName) reads one custom metadata record by its name (Custom Metadata Type Methods (在新標籤頁中開啟), Apex Reference Guide, checked 2026-10-27). ⟲

In a flow, it’s the same idea: the first element is a decision. ⟲

A bypass at the top of a flow A record-triggered flow, top to bottom. It starts when a Work Order is created or changes. The first element is a question: is the bypass on for this user, through a custom permission or a setting for the org, a profile or one user? If yes, the flow ends and does nothing; the record still saves, with no side effects. If no, the flow carries on to its normal work, highlighted: publish the status to the partners, for everyone else. Underneath: the check comes first; switch it on for the migration user, and the flow steps aside while the record saves. {"author": "Steve Simpson", "blueprint": "1.0.0", "builder": "standard 1.48.0", "built": "2026-10-27", "id": "DGM-DA-MG-33", "rights": "\u00a9 2026 Twinshark LLC. All rights reserved.", "template": "flow/decision 0.1.0", "theme": "stevetecharc 1.4.0"} A Work Order is created or changes the record-triggered flow starts Is the bypass on for this user? a custom permission, or a setting for the org, a profile or one user End: do nothing the record still saves; no side effects Publish the status to the partners the normal work, for everyone else yes no The check comes first. Switch it on for the migration user, and the flow steps aside while the record saves. HOW TO READ IT a step the step that matters most a question an answer yes goes right to an answer; no goes down to the next question © 2026 Twinshark LLC · stevetecharc.com
點擊放大

The check comes first. Switched on, the flow steps aside. ⟲

The decision’s condition reads the same two switches, through flow’s global variables: $Permission is “the custom permission access of the user running the flow,” and $Setup reads hierarchy custom settings (Global Variables Resource (在新標籤頁中開啟), Salesforce Help, checked 2026-10-27). As a formula resource: ⟲

{!$Permission.Bypass_Automation} || {!$Setup.Automation_Bypass__c.Disable_Flows__c}

In a validation rule, the bypass is one more condition. Here’s R12’s install rule, with the migration user allowed through (the field names are examples): ⟲

AND(
NOT($Permission.Bypass_Automation),
ISPICKVAL(Status, "Completed"),
Install_Required__c,
NOT(Install_Checklist_Complete__c)
)

Validation rules reference a custom permission as $Permission.Custom_Permission_Name (How to Reference a Custom Permission in a Formula, Workflow Rule, or Validation Rule (在新標籤頁中開啟), Salesforce Help, checked 2026-10-27). ⟲

Salesforce’s decision guide calls custom permissions “the modern, scalable standard for implementing bypass logic,” and notes a bypass can be granted to one user, “or even temporarily with a specific expiration date/time” (Record-Triggered Automation (在新標籤頁中開啟), checked 2026-10-27). That’s the migration window, built into the grant. ⟲

These are examples to adapt, not a framework to paste in: build yours, test it in a sandbox, and test that the switch turns back off. And remember what you’ve built. A bypass is a permission to skip business rules. Grant it to the migration user for the migration window, record who has it, and take it away when the load is done (module 4 puts that in the runbook). ⟲

Test knowledge. Know the three places to keep a bypass and who each applies to: a custom permission (only the users whose permission sets grant it; checked with $Permission in flows and validation rules, FeatureManagement.checkPermission in Apex), a hierarchy custom setting (the org, a profile or a user, the most specific value winning; $Setup in flows and formulas, getInstance() in Apex), and custom metadata (one switch per automation, deployable). ⟲

繞過並不意味著遷移使用者可以無視 Salesforce 中的每一條規則。這個自動化應該被繞過,那個必須依然執行;一條保護基本不變數的驗證規則依然重要,一條通知則不重要;一個下游整合需要被抑制,一個必需的關係依然需要檢查。所以我要的繞過是有意的、有範圍的,而不是 Migration_Mode__c = true,於是一切都無所謂了。遷移路徑依然有規則,只是那些適合遷移的規則。

而且繞過應該代表一種運維上下文,而不是一個意外。一個專門的遷移身分(模組 2)、一項自訂權限、配置後設資料、一個功能開關,或它們的組合,都可以識別出經過批准的遷移工作。身分可以是控制的一部分,但我不希望每一個自動化都硬編碼成 User.Name = 'Migration User'。那很脆弱。表達出意圖:如果這是一次經過批准的遷移操作,就跳過這個副作用。

「當商機為 Closed Won 時,Close Date 必填」是一條真正的資料不變數;對歷史商機也要保留它。一條強制填寫三年前才引入的當前流程欄位的規則就不同了:十年前的記錄從來沒有這個欄位,編造一個值只會讓資料更糟。問題不是「我們要不要關掉驗證規則?」而是**哪些規則代表持久的資料真相,哪些代表今天的互動流程?**這是資料架構師的問題。

Steve Trucking has one of each. Every Work Order must have a Retail Partner: that’s enduring truth, and it stays on for the load; a RouteDesk delivery without one goes to quarantine (module 1). But requirement R12 says an install can’t be closed without a completed checklist and specific photos, the water line, the drain line, the level. That’s today’s process, built for crews with the new mobile app. RouteDesk’s completed installs never had those photos. Bypass that rule for the migration identity, and load them as completed. Don’t invent photos. ⟲

要警惕的訊號是:目標要求一個值,源資料裡沒有,於是「統統填上 ‘Unknown’ 就好了」。如果 Unknown 是一個經過批准、確實描述了狀態的值,那沒問題。如果我們是為了通過驗證而插入假值,那就是在為了迎合應用而破壞資料。我寧願設計一個遷移例外、一個可為空的歷史欄位、一條轉換規則或一個遺留狀態值,也不願假裝我們知道自己並不知道的東西。

自動化會把「零的個數」成倍放大

Section titled “自動化會把「零的個數」成倍放大 ”

載入 200 萬個客戶;自動化為每個客戶建立 2 個任務:400 萬個任務。這是有意的,還是一個意外?然後每個任務又觸發另一個 flow,客戶的自動化更新一個父記錄,釋出一個事件,重新計算別的東西。遷移的效能不是 Bulk API 插入客戶的速度。真正的工作負載是這些插入所產生的事務圖。「零的個數」會通過自動化成倍放大。

Now zoom in on RouteDesk’s three red arrows and count. ⟲

Automation multiplies the Number of Zeros On the left, highlighted, the load: 196,400 Work Orders, about 190,000 of them already delivered. On the right, what normal automation would reach: Snowflake, for status history; the partners, Redrock, Keystone and Brightwave; the finance ERP, which invoices the partners; and the Recipients, who get day-before texts. First, every arrow is red with an X: 196,400 change events to Snowflake, 190,000 old statuses to the partners, delivery counts already invoiced to the finance ERP, and texts for old deliveries to the Recipients. Then the controlled path: the red arrows are gone; Snowflake gets one backfill after the load, the Recipients get texts only for the open deliveries, as normal, and nothing goes to the partners or the finance ERP. Underneath: the load's real size is every record times everything each record sets off; keep only the outcomes you need. THE LOAD WHAT NORMAL AUTOMATION WOULD DO 196,400 Work Orders about 190,000 already delivered Snowflake status history The partners Redrock, Keystone, Brightwave Finance ERP invoices the partners Recipients day-before texts 196,400 change events 190,000 old statuses counts already invoiced texts for old deliveries The load's real size is every record times everything each record sets off. Keep only the outcomes you need. HOW TO READ IT the load © 2026 Twinshark LLC · stevetecharc.com
點擊放大

Every record, times everything it sets off. ⟲

Chapter 9 turned on Change Data Capture for Work Orders, so Snowflake’s subscriber receives a change event for every create. That’s about 196,400 events in one weekend, and without an add-on the daily allocation for delivered events is 50,000 in Performance and Unlimited Editions, counted per subscriber (Change Data Capture Allocations (在新標籤頁中開啟), checked 2026-10-27). The partners would get status messages for about 190,000 deliveries they closed weeks ago. The finance ERP would count deliveries it has already invoiced, and the partners would be billed twice. And Recipients would get texts about deliveries that already happened. ⟲

Automation multiplies the Number of Zeros On the left, highlighted, the load: 196,400 Work Orders, about 190,000 of them already delivered. On the right, what normal automation would reach: Snowflake, for status history; the partners, Redrock, Keystone and Brightwave; the finance ERP, which invoices the partners; and the Recipients, who get day-before texts. First, every arrow is red with an X: 196,400 change events to Snowflake, 190,000 old statuses to the partners, delivery counts already invoiced to the finance ERP, and texts for old deliveries to the Recipients. Then the controlled path: the red arrows are gone; Snowflake gets one backfill after the load, the Recipients get texts only for the open deliveries, as normal, and nothing goes to the partners or the finance ERP. Underneath: the load's real size is every record times everything each record sets off; keep only the outcomes you need. {"author": "Steve Simpson", "blueprint": "1.0.0", "builder": "standard 1.48.0", "built": "2026-10-27", "id": "DGM-DA-MG-32", "rights": "\u00a9 2026 Twinshark LLC. All rights reserved.", "template": "cells 0.4.0", "theme": "stevetecharc 1.4.0"} THE LOAD WHAT NORMAL AUTOMATION WOULD DO 196,400 Work Orders about 190,000 already delivered Snowflake status history The partners Redrock, Keystone, Brightwave Finance ERP invoices the partners Recipients day-before texts one backfill, after the load open ones only, as normal The load's real size is every record times everything each record sets off. Keep only the outcomes you need. HOW TO READ IT the load © 2026 Twinshark LLC · stevetecharc.com
點擊放大

Keep only the outcomes you need: one backfill, texts for the open deliveries, nothing to partners or finance. ⟲

外部的副作用更糟。客戶郵件、賬單請求、被生產系統消費的事件、ERP 呼叫、支援工單、營銷更新:那些系統不知道這是遷移資料,而一旦訊息離開了 Salesforce,可能就無法撤回了。第 9 章給了我們整合資料契約;在遷移規劃期間,要決定這些箭頭中哪些可以執行,哪些要被抑制,哪些在切換之後用一次同步來代替。這個決定屬於切換計劃。

彙總和其他派生值:載入一個父記錄,然後是幾百萬個子記錄,每加一個子記錄就重新計算一次?也許吧。通常,把一切都載入完再計算一次要便宜得多。問題是,派生結果是必須在遷移期間逐條記錄地維護,還是可以在依賴資料完整之後再建立。這還是那個「不需要 / 模擬 / 推遲」的決定。

共用也是派生資料。建立和轉移記錄會觸發共用規則的計算,在一次大型載入中,這可能意味著非常漫長的計算或超時。Salesforce 允許管理員推遲共用計算(共用規則和組成員關係),之後再恢復,但這個功能預設沒有開啟:要由 Salesforce 客戶支援來啟用。恢復時,你必須執行一次完整的重新計算,而且為了保護資料完整性,有些共用變化依然會被立即計算(Defer Sharing Calculations (在新標籤頁中開啟))。為它做好計劃,也為重新計算的時間做好計劃。

Deferring has limits of its own. The catch-up usually runs as batch Apex, and that shares the org’s daily allowance of asynchronous Apex executions: “250,000 or the number of applicable user licenses in your org multiplied by 200, whichever is greater.” Only five batch jobs can be queued or active at once, with up to 100 more waiting in the flex queue (Execution Governors and Limits (在新標籤頁中開啟), Apex Developer Guide, Winter ‘27, checked 2026-10-27). Your catch-up competes with every other batch job in the org, so schedule it, and size it. ⟲

Test knowledge. Large loads trigger sharing recalculation. Salesforce Support can enable deferred sharing calculations (sharing rules and group membership), which you resume and recalculate after the load. Deferred work usually runs as batch Apex, within the daily asynchronous Apex limit and five concurrent batch jobs. ⟲

And sometimes the logic you need is simply too slow to load through. This is the special case module 1 mentioned. A process that takes a second or two per record is fine for users; for hundreds of thousands of records in a cutover window it means days, and trying to simulate an intricate object model in the load can mean a dozen tables. The technique I use: load into a staging object first, a light custom object with no automation that holds the import fields and lookups, then let a batch process work through it, calling the platform’s own logic to build the real records. The status on each staging row lets the batch work in chunks, pause and resume, and the original import fields stay alongside the records they created for tracing. You get the data in fast and catch up on the processing afterward. ⟲

為最終狀態而設計,並把它寫下來

Section titled “為最終狀態而設計,並把它寫下來 ”

目標不是「執行生產環境的自動化」。而是**到達正確的生產狀態,**這兩者並不相同。對於一個新客戶,正常的處理會推算出一個分類,建立一個入職任務,傳送一條通知,併發布到另一個系統。對於一個遷移過來的歷史客戶,正確的最終狀態可能是:分類要,入職任務不要,歡迎通知不要,外部發布也許要,取決於同步計劃。盲目地執行正常的自動化,只會重現一個並非為遷移而設計的流程。

對於一次嚴肅的遷移,把它寫成一份自動化清單:

自動化正常行為遷移決定必需的遷移結果
Status out to partnersSend each status change to Redrock, Keystone, BrightwaveDon’t need itNone: the partners already have it
Change Data Capture to SnowflakeA change event per Work OrderDeferOne backfill of status history after the load
Delivery counts to financeCount each completed delivery for invoicingDon’t need itNone: already invoiced; reconcile the count instead
Day-before textText the Recipient with a tracking linkRun deliberately, open deliveries onlyMonday’s Recipients get the link; none for delivered ones
Work Order statusSet by the crews’ appSimulateStatus mapped in the preparation data store
Install checklist and photos (R12)Block closing an install without themBypass for the migration identityCompleted installs load as completed; no invented photos
Every Work Order has a partnerReject a Work Order without oneKeepMissing partner: quarantined before the load

現在決定是可見的:我們可以評審它、測試它、演練它,並在載入之後驗證它。

不要讓生產環境成為你第一次使用遷移模式的地方。演練應該測試遷移身分、繞過控制、保持啟用的自動化、模擬的結果、推遲的流程以及恢復到正常模式,然後檢查:有沒有不該觸發的東西觸發了,有沒有該發生的事沒有發生,最終狀態是否與架構相符?這就是為什麼演練需要真實的自動化配置,或者儘可能接近它。

重新啟用是一個切換步驟:明確的,有指定的負責人、預期的時間和驗證。不是「記得把 flow 重新開啟」。在正常執行恢復並經過驗證之前,系統還沒有為使用者準備好(模組 4 把它放進了執行手冊)。

And beware the catch-up storm. We suppressed downstream synchronization while loading RouteDesk’s records; now we switch the integration back on. Does it see five million “new” records and try to send them all? Maybe the downstream system already received them another way, maybe only changes after the cutover watermark should go, maybe it needs a controlled initial sync. The automation decision and the integration decision have to work together. Turning automation back on isn’t enough: know what it will do when it wakes up. For Steve Trucking, the status flows and the Change Data Capture subscriber should see only the changes made after cutover, never the weekend’s load. ⟲

現在再加上會對一個新案例、一個被修改的客戶、一個已釋出的事件或佇列中的一個任務做出反應的代理程式。遷移會以機器的規模製造資料模式;我們希望代理程式對每一條遷移過來的記錄都做出反應嗎?大概不希望它意外地這樣做。由代理程式觸發的流程,和 flow、觸發器、通知、整合和事件一樣,都屬於這份清單;如果遷移上下文應該抑制它們,就有意識地把這一點設計進去。

**考試之外:AI 改變了什麼。**代理程式是另一種副作用,它可能會對遷移的資料自主地做出反應。像對待任何其他自動化一樣對待由代理程式觸發的操作:決定是執行、模擬、推遲還是抑制它們,並在演練中測試這個決定。

  • 對每一類遷移資料,哪些自動化執行、不需要、被模擬或被推遲,並清楚關掉一個自動化就意味著要為它的業務邏輯負責。
  • 哪些驗證規則代表持久的資料真相,哪些是需要針對遷移特殊處理的當前流程規則。
  • How scoped bypasses are designed into every automation from the start, tested on and off, and deployed long before they’re needed, without an unrestricted “skip everything” path. ⟲
  • 派生資料、共用重新計算和緩慢的平台邏輯如何處理:在載入之後、推遲處理,還是通過暫存物件。
  • 哪些外部副作用和整合被抑制或有意識地補發,以及演練和切換如何證明正常的自動化已被安全恢復。

遷移的成功,不是因為每個 flow 都運行了、每個觸發器都觸發了、每條驗證規則都執行了。那是正常的事務行為,而遷移有一項不同的工作:把資料移入新的架構,保留重要的真相,建立我們需要的派生值,避免錯誤的副作用,讓系統保持可控,然後讓它恢復正常。對每一個自動化:不需要它、模擬它、推遲它,或有意讓它執行。但要讓它成為一個決定。不要讓五百萬條記錄替你決定。