Bỏ qua để đến nội dung

Tải dữ liệu ở khối lượng lớn

Cũng có bằng 19 ngôn ngữ khác

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

In a greenhouse packing hall, three rows of tall plant trolleys, one all red flowers, one all yellow and one all white, wait by the open door.
Hình ảnh được tạo bằng AI

Mô-đun 2 trong 5 của chương Chuyển đổi và đồng bộ dữ liệu, chương 10 của khóa học Data Architect. Mỗi mô-đun có thể đọc độc lập. Trước: Chuyển đổi dữ liệu trước hết là một dự án chất lượng · Tiếp theo: Tự động hóa trong lúc tải

Câu hỏi mô-đun này trả lời: Số chữ số 0 thay đổi cách bạn tải dữ liệu vào Salesforce thế nào?

Mười bản ghi? Tôi gần như có thể gõ tay. Một nghìn? Giờ tôi cần một công cụ. Một triệu? Đó là một bài toán kiến trúc. Thao tác không thay đổi (tạo hoặc cập nhật bản ghi), nhưng Số chữ số 0 thay đổi cách tôi làm. Chúng ta đã thấy điều đó với mô hình hóa, truy vấn, chia sẻ và tích hợp, và chuyển đổi dữ liệu cũng không khác. Ở khối lượng lớn, tôi quan tâm đến cách tôi di chuyển dữ liệu, cách tôi chia nó thành các phần việc, nó di chuyển theo thứ tự nào, Salesforce còn đang làm gì khác trong lúc tôi tải, tôi khôi phục thế nào khi có gì đó thất bại, và tôi có chạy lại được toàn bộ không.

Same landscape, same amber arrow as module 1: RouteDesk’s open work coming into Salesforce the weekend RouteDesk retires. ⟲

The arrow that runs once Steve Trucking's landscape from Checkpoint 1, in the same places, the weekend RouteDesk retires: people on the left, Salesforce with Field Service in the middle with the Retail Partner portal and the tracking page, the integration layer from chapter 9 to its right, and the systems around it: Snowflake, FleetLink, the finance ERP, photo storage, and RouteDesk, retiring, with 8 years and about 5 million deliveries. One new arrow, in amber, the migration this module zooms in on, carries what's still open from RouteDesk into Salesforce, migrated once. Underneath: one arrow runs once and then disappears; a migration is an integration with an end. {"author": "Steve Simpson", "blueprint": "1.0.1", "builder": "standard 1.54.0", "built": "2026-10-30", "id": "DGM-DA-MG-10", "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 a shared certificate: trust, no direct call the migration we zoom in on Checkpoint 1's landscape, the weekend RouteDesk retires. One arrow runs once and then disappears: a migration is an integration with an end. © 2026 Twinshark LLC · stevetecharc.com
Nhấp để phóng to

Module 1 decided what moves on this arrow. This module is about how it moves. ⟲

Module 1 decided what comes in: the deliveries not yet made and the ones still inside the 60-day claim window, about 196,400 deliveries. Each one becomes a Work Order, with its line items (about 1.6 per delivery, so about 314,000) and its Service Appointment (about 196,400 more). That’s roughly 707,000 records, prepared in the preparation data store and ready to go. Not millions, but well past anything I’d send one record at a time. So, how do they get in? ⟲

Khi dạy Bulk API, tôi dùng hình ảnh ngân hàng. Bạn bước vào với một xấp phiếu gửi tiền, và giao dịch viên nhận 200 phiếu rồi bảo bạn quay lại cuối hàng. Với một triệu bản ghi, đó là 5.000 lượt xếp hàng, 5.000 lệnh gọi API. Trong lúc đó một chiếc xe tải đỗ ở hông ngân hàng, dỡ xuống một khối lượng tiền gửi khổng lồ, và hai mươi phút sau lái đi trong khi bạn vẫn còn đứng xếp hàng. Đó là bến bốc dỡ, và tên của nó là Bulk API.

The 200 is still real. A REST sObject Collections request takes “up to 200 records” (Create Records Using sObject Collections (mở trong thẻ mới), REST API Developer Guide), and a SOAP create() call the same: “If a create request exceeds 200 records, then the entire operation fails” (create() (mở trong thẻ mới), SOAP API Developer Guide; both checked 2026-10-27). Every 200 more records is another call. RouteDesk’s 707,000 records would be over 3,500 trips to the teller. ⟲

The teller window and the loading dock Two equal panels. The teller window, the synchronous APIs: each trip, up to 200 records a call; a million records, about 5,000 calls, back of the line each time; you get back an answer for every record, right away; it fits singles and sets, fewer than about 2,000 records. The loading dock, the Bulk API: each trip, whole files that Salesforce splits into batches; a million records, a handful of calls; you get back a job ID now and the results later; it fits bulk, more than about 2,000 records. Underneath: same records, different door; over about 2,000 records, Salesforce points you to the loading dock. {"author": "Steve Simpson", "blueprint": "1.0.0", "builder": "standard 1.46.0", "built": "2026-10-27", "id": "DGM-DA-MG-20", "rights": "\u00a9 2026 Twinshark LLC. All rights reserved.", "template": "comparison 0.4.0", "theme": "stevetecharc 1.4.0"} The teller window the synchronous APIs EACH TRIP Up to 200 records a call A MILLION RECORDS About 5,000 calls, back of the line each time YOU GET BACK An answer for every record, right away FITS Singles and sets: fewer than about 2,000 records The loading dock the Bulk API EACH TRIP Whole files; Salesforce splits them into batches A MILLION RECORDS A handful of calls YOU GET BACK A job ID now, the results later FITS Bulk: more than about 2,000 records Same records, different door. Over about 2,000 records, Salesforce points you to the loading dock. © 2026 Twinshark LLC · stevetecharc.com
Nhấp để phóng to

Same records, different door. ⟲

Bến bốc dỡ có năm bước:

  1. Mở tác vụ. Bấm chiếc chuông đỏ và lấy một tấm vé: ID tác vụ.
  2. Tải lên. Bến mở cửa và bạn chất các tệp CSV của mình theo tấm vé đó, một tệp hay một trăm tệp.
  3. Đóng tác vụ. Salesforce không biết bạn đã xong cho đến khi bạn nhấn nút xanh lớn: tải lên hoàn tất. Giờ nó bắt đầu xử lý.
  4. “Tới chưa?” Giống như các con tôi ở ghế sau: bạn hỏi, với ID tác vụ của mình, xem nó đã xong chưa. Xong chưa? Xong chưa?
  5. Lấy kết quả. Tải xuống các bản ghi thành công (cùng ID Salesforce mới của chúng) hoặc các bản ghi thất bại (cùng lỗi của chúng).
Five steps at the loading dock The loading dock in five steps, left to right. 1, open the job: get a ticket, the job ID. 2, upload: one file or a hundred. 3, close the job: upload complete, now it processes. 4, are we there yet?: ask with the job ID. 5, highlighted, get the results: successes with new IDs, failures with errors. Underneath: submit, wait, collect; nobody answers per record, so you keep track of the job. {"author": "Steve Simpson", "blueprint": "1.0.0", "builder": "standard 1.46.0", "built": "2026-10-27", "id": "DGM-DA-MG-21", "rights": "\u00a9 2026 Twinshark LLC. All rights reserved.", "template": "cells 0.3.0", "theme": "stevetecharc 1.4.0"} THE LOADING DOCK 1. Open the job get a ticket: the job ID 2. Upload one file or a hundred 3. Close the job upload complete: now it processes 4. Are we there yet? ask with the job ID 5. Get the results successes with new IDs, failures with errors job ID files in processing done Submit, wait, collect. Nobody answers per record, so you keep track of the job. HOW TO READ IT the step migrations depend on: keep every result © 2026 Twinshark LLC · stevetecharc.com
Nhấp để phóng to

Submit, wait, collect. ⟲

Một triệu bản ghi tốn một nắm lệnh gọi thay vì hàng nghìn. Nhưng hãy để ý điều đã thay đổi: công việc là bất đồng bộ. Bạn không nhận câu trả lời cho từng bản ghi; bạn gửi, chờ, rồi thu về. Vì vậy bên gọi cần biết cái gì đã được gửi, cái gì vẫn đang xử lý, cái gì đã hoàn tất, cái gì thất bại và cái gì đã quay về. Đó không phải là chi tiết API. Đó là kiểm soát chuyển đổi.

Có hai phiên bản, và bạn đang dùng phiên bản nào là điều quan trọng.

  • Bulk API 2.0 is the one to start with. You upload the data for a job and Salesforce splits it into batches for you, retries for you and runs them in parallel. A job can take 150 MB, measured after Salesforce encodes it, so Salesforce advises uploading no more than 100 MB of CSV per job. ⟲
  • Bulk API (1.0) makes you create the batches yourself, up to 10,000 records each. It’s older, but it still has two levers 2.0 doesn’t give you: serial mode for loads, and PK chunking for very large exports (module 5). ⟲

Both share a rolling 24-hour allowance of 15,000 batches, and either can load up to 150 million records in 24 hours. Job results are kept for seven days after the job completes (Bulk API and Bulk API 2.0 Limits and Allocations (mở trong thẻ mới), checked 2026-10-27). Salesforce’s line between the doors: “Any data operation that includes more than 2,000 records is a good candidate for Bulk API 2.0”; below that, “bulkified” synchronous calls are fine (Loading Data from the API (mở trong thẻ mới), Best Practices for Deployments with Large Data Volumes, Winter ‘27, checked 2026-10-27). Those are today’s numbers: check them before you plan around them. ⟲

Từng bản ghi, theo tập và hàng loạt là cách tôi nghĩ về hình dạng của công việc: một cập nhật đơn lẻ từ một thao tác người dùng, vài trăm bản ghi liên quan từ một quy trình nghiệp vụ, hàng triệu bản ghi lịch sử trong một đợt chuyển đổi. Đó không phải là tên sản phẩm. Hãy hỏi hình dạng của công việc là gì trước khi chọn công cụ.

Test knowledge. Know when the Bulk API is the answer: more than about 2,000 records, asynchronous, a job you submit and collect. Know the two versions apart: Bulk API 2.0 splits the batches for you and runs them in parallel; Bulk API (1.0) has you build batches of up to 10,000 records, and only it offers serial mode and PK chunking. Both share 15,000 batches in a rolling 24 hours. ⟲

“Chúng tôi sẽ dùng Bulk API.” Được. Điều đó không cho tôi biết đối tượng nào tải trước, insert hay upsert, khóa bên ngoài là gì, quan hệ được dựng lại thế nào, chuyện gì xảy ra khi một số bản ghi thất bại, các tác vụ có chạy song song được không, công việc song song có tranh giành cùng các bản ghi cha không, tự động hóa nào sẽ chạy, hay chúng ta sẽ đối chiếu và chạy lại thế nào. Bulk API giải quyết một bài toán vận chuyển. Nó không giải quyết đợt chuyển đổi.

The order comes from the model, and module 1 drew it for RouteDesk: reference data first, then the Work Orders, then their line items and appointments, then the claim Cases that point at them (Preserve the Source Identity, and Load by Keys). Each wave is its own job, and the next one doesn’t start until the last one’s results are in. Junction objects depend on two parents, self-referencing hierarchies may need several passes, and circular relationships may need records first and relationships second. Don’t discover these on cutover weekend. ⟲

Đôi khi bạn tải bản ghi trước, rồi mới đến quan hệ. Một công ty mẹ, một công ty con và một công ty con khu vực đều được tạo trong đợt chuyển đổi. Thay vì giải quyết mọi quan hệ trong một lượt, hãy tải các tài khoản với khóa nguồn ổn định của chúng, rồi chạy lượt thứ hai để thiết lập phân cấp. Cùng ý tưởng đó giúp ích với tra cứu tự tham chiếu và phụ thuộc vòng. Mục tiêu không phải là một lượt. Mà là một kết quả tất định, lặp lại được.

Insert says create this as new. Update says I already know the Salesforce record I’m changing. Upsert says use this key to find out whether the record exists; update it if it does, create it if it doesn’t. With stable External IDs, upsert makes rehearsals far easier: load, find a transformation problem, fix it, rerun, without the run assuming everything is a first-time insert. Keys are architecture, not just integration plumbing. RouteDesk’s Work Orders upsert on the partner key, the same field the integration uses, so a manifest Redrock resends on cutover weekend updates the migrated record instead of duplicating it. ⟲

Upsert has a price, though. Salesforce’s own Large Data Volumes guide ranks the operations: “insert() is fastest, update() is next, and upsert() is next after that. If possible, also break upsert() into two operations: create() and update()” (Loading Data from the API (mở trong thẻ mới), checked 2026-10-27). How do you know which records are new and which already exist? The preparation data store knows, because it pulled down what Salesforce already has and keeps the IDs that came back (module 1). So the 190,000 delivered Work Orders that nothing in Salesforce has touched can go in as a plain insert, and only the open ones the integration may already have created need the upsert. ⟲

Two more lines from the same guide. Load clean data: “Errors in batches trigger single-row processing for that batch, and that processing heavily impacts performance.” That’s module 1 paying off at the loading dock. And when you update, “send only fields that have changed.” A reload that resends every field of 196,400 Work Orders does work nobody asked for. ⟲

Nhưng upsert không phải phép màu. Nếu chiến lược khóa sai, thao tác sẽ sai. Hai bản ghi nguồn cho cùng một khách hàng với hai khóa khác nhau là hai bản ghi đối với Salesforce; một khóa nguồn có thể nhận diện nhiều bản ghi đích nghĩa là chúng ta đã hiểu sai quan hệ số lượng. Công việc chất lượng của mô-đun 1 vẫn quan trọng; một tính năng API không thay thế được nó.

Test knowledge. Insert is the fastest operation, then update, then upsert; Salesforce suggests splitting an upsert into creates and updates where you can. Upsert needs an External ID, and it’s what makes reruns safe. Load clean data, because errors in a Bulk API batch push that batch into slow single-row processing, and send only the fields that changed. ⟲

Song song thì nhanh hơn, cho đến khi không còn như vậy

Phần tiêu đề “Song song thì nhanh hơn, cho đến khi không còn như vậy ”

Xử lý song song tăng thông lượng. Nhưng nếu nhiều bản ghi trong lần tải trỏ đến cùng một bản ghi cha, các giao dịch tranh giành khóa trên bản ghi cha đó, và thứ chúng ta làm để đi nhanh hơn lại tạo ra tranh chấp khóa, lỗi và thử lại. Đó lại là các điểm nóng của chương 7: nếu một triệu bản ghi con hội tụ về vài bản ghi cha, hình dạng của dữ liệu quan trọng đối với việc tải. Khi hai lô cùng chờ một khóa mà lô kia đang giữ, bạn có một bế tắc (deadlock), hai chiếc xe kẹt cứng ở ngã tư.

RouteDesk is exactly that shape. Almost 196,400 Work Orders, and nearly every one points at one of three Retail Partner Accounts. Load them in parallel in the order RouteDesk exported them, and every batch holds Work Orders for all three partners. ⟲

Sort the load by parent Three batches of Work Orders loading in parallel on the left; on the right, their parents, the Retail Partner Accounts Keystone, Redrock and Brightwave. First, each batch holds Work Orders from all three partners, so all three need Redrock at the same moment: batch 2 locks it, and batches 1 and 3 wait, their arrows red with an X. Then the same work, sorted by partner, tagged "sorted": batch 1 holds only Keystone's Work Orders, batch 2 only Redrock's, batch 3 only Brightwave's, and each goes to its own parent. Underneath: batches that share parents wait on each other's locks; sort the file by parent, and each batch works on its own. BATCHES, IN PARALLEL PARENTS: THE RETAIL PARTNER ACCOUNTS Batch 1 Work Orders from all three partners Batch 2 Work Orders from all three partners Batch 3 Work Orders from all three partners Redrock Retail Partner Account Keystone Retail Partner Account Brightwave Retail Partner Account locks waits waits Batches that share parents wait on each other's locks. Sort the file by parent, and each batch works on its own. © 2026 Twinshark LLC · stevetecharc.com
Nhấp để phóng to

In export order, every batch needs every parent. One locks, the others wait. ⟲

Two levers. First, sort the files by parent, so the children of one parent travel together in the same batch instead of being spread across batches that collide. Salesforce gives the same advice: “When changing child records, group them by parent—group records by the field ParentId in the same batch to minimize locking conflicts” (Loading Data from the API (mở trong thẻ mới), checked 2026-10-27). ⟲

Sort the load by parent Three batches of Work Orders loading in parallel on the left; on the right, their parents, the Retail Partner Accounts Keystone, Redrock and Brightwave. First, each batch holds Work Orders from all three partners, so all three need Redrock at the same moment: batch 2 locks it, and batches 1 and 3 wait, their arrows red with an X. Then the same work, sorted by partner, tagged "sorted": batch 1 holds only Keystone's Work Orders, batch 2 only Redrock's, batch 3 only Brightwave's, and each goes to its own parent. Underneath: batches that share parents wait on each other's locks; sort the file by parent, and each batch works on its own. {"author": "Steve Simpson", "blueprint": "1.0.0", "builder": "standard 1.46.0", "built": "2026-10-27", "id": "DGM-DA-MG-22", "rights": "\u00a9 2026 Twinshark LLC. All rights reserved.", "template": "cells 0.3.0", "theme": "stevetecharc 1.4.0"} BATCHES, IN PARALLEL PARENTS: THE RETAIL PARTNER ACCOUNTS Batch 1 Keystone's Work Orders only sorted Batch 2 Redrock's Work Orders only sorted Batch 3 Brightwave's Work Orders only sorted Redrock Retail Partner Account Keystone Retail Partner Account Brightwave Retail Partner Account its own parent its own parent its own parent Batches that share parents wait on each other's locks. Sort the file by parent, and each batch works on its own. © 2026 Twinshark LLC · stevetecharc.com
Nhấp để phóng to

Sorted by partner, each batch works on its own parent. ⟲

Second, on Bulk API 1.0, serial mode processes one batch at a time: slower, but it removes the contention. I reach for serial mode when the data is complex and we’re running into collisions and timeouts. Salesforce’s own guide is more cautious: serial mode “is used only when previously submitted asynchronous jobs have accidentally produced contention because of locks. Use only when advised by Salesforce” (Limits (mở trong thẻ mới), Bulk API 2.0 and Bulk API Developer Guide, checked 2026-10-27). So sort first, and treat serial as the fallback. And it’s only on the older dock: Bulk API 2.0’s job reference says “Currently only parallel mode is supported,” and if other modes ever arrive, “the mode will be chosen automatically by the API and will not be user configurable” (Create a Job (mở trong thẻ mới), Bulk API 2.0, checked 2026-10-27). A load that needs serial processing is a reason to use Bulk API 1.0. ⟲

Serial mode is a setting on the job, chosen when you create it. On Bulk API 1.0, RouteDesk’s Work Orders would be: ⟲

POST /services/async/68.0/job
{
"operation": "upsert",
"object": "WorkOrder",
"externalIdFieldName": "Partner_Delivery_Key__c",
"contentType": "CSV",
"concurrencyMode": "Serial"
}

Leave concurrencyMode out and you get Parallel, the default. Salesforce’s job reference says when to change it: “If parallel mode results in too many failed records or failed jobs, submit the job with Serial concurrency mode,” and adds that it “can significantly increase the processing time” (JobInfo (mở trong thẻ mới), Bulk API 2.0 and Bulk API Developer Guide, checked 2026-10-31). ⟲

And if three parents are too few for any sorting to help, look at the model. Checkpoint 1 already offered a way to spread them: link Work Orders to a child Account per distribution center, so nine parents share the load instead of three. That’s a design decision, made before the migration, not a loader setting. ⟲

Tôi không bắt đầu bằng “luôn song song” hay “luôn tuần tự”. Tôi nhìn vào hình dạng quan hệ, các bản ghi cha nóng, tự động hóa được kích hoạt, những gì khác bị khóa, và những gì đã xảy ra khi diễn tập. Rồi tôi mới chọn. Đúng trước, rồi mới nhanh.

Test knowledge. Parallel loads lock parent records. When many children share a few parents, expect “unable to lock row” errors: sort the load file by parent so each batch touches as few parents as possible. Serial mode (Bulk API 1.0 only) removes the contention at the cost of speed; Salesforce reserves it for lock contention the sorting didn’t solve. ⟲

Kích thước lô là một quyết định tinh chỉnh

Phần tiêu đề “Kích thước lô là một quyết định tinh chỉnh ”

Người ta muốn một con số thần kỳ. Tôi không có. Kích thước đúng phụ thuộc vào đối tượng, độ phức tạp của bản ghi, tự động hóa, quan hệ, khóa, payload và cơ chế. Quá lớn thì lỗi trở nên đắt đỏ và giao dịch làm quá nhiều việc; quá nhỏ thì chi phí phụ lấn át và lượt chạy mất thời gian lâu hơn nhiều so với cần thiết (và trên 1.0, đốt hạn mức lô của bạn). Hãy bắt đầu trong giới hạn mà công cụ hỗ trợ, rồi đo với dữ liệu đại diện.

And the rehearsal data needs the same shape as production. Twenty million records in production, ten thousand in the test, and everything flies: what did we prove? Not much about scale. The test doesn’t need every record, but it must expose the architecture: heavy concentration on a few parents, millions of children, large text fields, complex relationships, historical skew, automation triggered by particular values. The Number of Zeros matters, and so does the shape behind the zeros. For RouteDesk that means a rehearsal set where a third of the Work Orders still point at Redrock. ⟲

Người dùng tải, và ai sở hữu các bản ghi

Phần tiêu đề “Người dùng tải, và ai sở hữu các bản ghi ”

For a substantial migration I want a dedicated migration identity, not someone’s personal admin account: for traceability, controlled permissions, automation decisions (module 3), monitoring and troubleshooting. A million records created by the migration user during cutover tells me something. A million created by Daniel Reyes because Daniel ran Data Loader on Saturday night mixes human identity with system activity. Give it the permissions the job needs, and don’t let it become a permanent mystery superuser nobody dares disable. ⟲

Then don’t confuse who loaded a record with who should own it. Created By is provenance; Owner is architecture, with sharing and business consequences. Set business ownership deliberately. Sometimes there’s no good answer in the source: the record’s owner left years ago, or never existed. It can be hard to assign records to active users, and I’ve created a dedicated “data load” user to own them. That’s sound practice with one condition from chapter 7: a user who owns more than 10,000 records of an object is ownership skew, so that owner should have no role, or a role of its own at the top of the hierarchy (Ownership Data Skew (mở trong thẻ mới)), and the records should have a path to real owners. Who owns the records, and where that owner sits in the role hierarchy, is an important decision the team makes for any bulk import, not something the loader defaults. For RouteDesk’s Work Orders, chapter 7’s question decides it: does ownership drive who sees a delivery? At Steve Trucking it doesn’t (partners see their own deliveries through the partner on the record), so one owner with no role is fine. ⟲

There are many ways to load data, and the tool matters less than how you use it. Salesforce’s Data Loader has been tried and true, but it’s aged: a desktop tool that works CSV by CSV. Its command-line version can be scripted and pointed at your preparation data store, which is how I’ve run repeated loads. Some tools connect a SQL database straight to Salesforce, copying data down and sending changes back with SQL. ETL and integration platforms do the same job at enterprise scale. And with the APIs you can drive the Bulk API directly: the Salesforce CLI’s sf data upsert bulk loads a CSV through Bulk API 2.0 with an External ID from one command (data upsert bulk (mở trong thẻ mới), Salesforce CLI Command Reference, checked 2026-10-27). You can even have AI write the small scripts that run each complex step. ⟲

Dù công cụ là gì, đây là điều tôi ưu tiên mạnh nhất: tôi không muốn đợt chuyển đổi trên production là lần đầu tiên chúng ta thực hiện đợt chuyển đổi, và tôi không muốn mỗi lần diễn tập là một cuộc phiêu lưu làm thủ công. Nếu bước 17 ghi “mở tệp CSV này, sắp xếp theo cột G, xóa các dòng trống, chép công thức này xuống, rồi chạy Data Loader với các thiết lập này”, tôi lo lắng. Mỗi bước thủ công là một cơ hội cho tệp sai, dòng bị sót, phiên bản cũ, sắp xếp sai, bộ lọc bị quên, một thiết lập khác với lúc diễn tập. Có những bước có thể không tránh được: hãy ghi lại và kiểm thử chúng. Nhưng mục tiêu là khả năng lặp lại, nên trích xuất, chuyển đổi, xác thực, tải, thu kết quả và đối chiếu phải chạy theo cùng một cách mỗi lần.

Nếu bạn lên lịch cho các lần tải, đừng lên lịch dày hơn mức chúng có thể hoàn tất. Một tác vụ mỗi giờ mà đôi khi mất chín mươi phút sẽ khởi động chồng lên chính nó; hãy kiểm tra lượt chạy trước đã xong chưa trước khi lượt tiếp theo bắt đầu.

Với mỗi lần tải, hãy giữ phiên bản đầu vào, tệp tải đã chuyển đổi, ID tác vụ, kết quả thành công và thất bại cùng lỗi của chúng, thời gian, số bản ghi và kết quả đối chiếu. Sau một đợt chuyển đổi lớn, sẽ có người hỏi “chuyện gì đã xảy ra với bản ghi này?” và tôi muốn có bằng chứng, chứ không phải “tôi nghĩ nó nằm trong tệp CSV thứ ba sáng thứ Bảy”. Kết quả hàng loạt chỉ được giữ bảy ngày, nên hãy tải chúng xuống ngay khi có. Hãy cho những sản phẩm này một vòng đời sau; đừng vứt chúng đi khi bạn vẫn còn cần chứng minh việc di chuyển.

Then bring the keys back. The success results carry each record’s new Salesforce ID next to the key you sent. Write them back into the preparation data store, on the row that produced the record: that’s the last frame of module 1’s three sets of keys. On the Zendesk migration I described in module 1, that’s what made everything else possible. With the Salesforce IDs back on every row, I could load in phases (accounts and contacts first, then the cases, then the comments and files that hang off them), and each phase found its parents by the IDs the last one returned. I could do a partial load: just the rows that failed, or just one group. And I could reload: fix a transformation, regenerate the affected rows, and send only those, knowing exactly which Salesforce records they’d update. Without the keys back, every rerun is a guess. ⟲

Quy mô lỗi cũng là một câu hỏi về Số chữ số 0. Hai mươi lỗi trên 100 là tệ; hai mươi trên 20 triệu vẫn cần điều tra nhưng là một tín hiệu khác. Hãy theo dõi tỷ lệ, không chỉ số lượng, và phân loại lỗi: xác thực, thiếu bản ghi cha, trùng khóa, khóa bản ghi, kiểu dữ liệu, tự động hóa, quyền hạn. Khi được phân loại, chúng cho bạn thấy các vấn đề kiến trúc thay vì một tệp lỗi khổng lồ.

Và hiệu năng không chỉ là số bản ghi mỗi giây. “Chúng tôi đã tăng gấp đôi thông lượng.” Cái gì đã thay đổi? Khóa, lỗi hay thử lại có tăng không? Tự động hóa phía sau có bị tụt lại, việc tính lại chia sẻ có bị dồn ứ, một tích hợp khác có bị quá tải không? Tổng thời gian chuyển giao có thực sự ngắn hơn không? Một đợt chuyển đổi không chạy trong chân không.

Test knowledge. The Bulk API’s success results return each record’s new Salesforce ID with the data you sent, and its failure results return each error; both are kept for seven days. Capture them, write the IDs back to the source or staging data, and you can load in phases, retry only the failures, and reconcile what landed. ⟲

Tải tài khoản, rồi liên hệ, rồi đơn hàng, mỗi thứ được kiểm thử riêng, không phải là một đợt chuyển đổi đã được kiểm thử. Tôi muốn một lần diễn tập đầy đủ, từ đầu đến cuối, với cùng trình tự, phép chuyển đổi, danh tính, chiến lược tự động hóa và đối chiếu, ở khối lượng đại diện. Các phụ thuộc xuất hiện giữa các bước: mười phút chậm trễ khiến lần tải tiếp theo bắt đầu sai thời điểm, một tỷ lệ lỗi bất ngờ tốn hàng giờ khắc phục, một lần tính lại chia sẻ làm xê dịch lịch trình. Lượt chạy đầy đủ cho bạn biết đợt chuyển đổi có chạy được không, không chỉ là từng lệnh có chạy được không.

If the rehearsal includes a performance or scale test, put Salesforce’s lead time in the plan. “All tests must be pre-approved. Unapproved testing is subject to throttling or blocking,” and for tests at 120 requests a second or below, the request goes in “at least one week before the testing date” (Salesforce Performance and Scale Test FAQs (mở trong thẻ mới), Salesforce Help, checked 2026-10-27). A rehearsal that gets throttled proves nothing about cutover weekend. ⟲

AI có thể viết script. Bạn vẫn chịu trách nhiệm về lượt chạy.

Phần tiêu đề “AI có thể viết script. Bạn vẫn chịu trách nhiệm về lượt chạy. ”

AI is very good at generating transformation scripts, load orchestration, error parsers, reconciliation queries and retry logic. Use it. But generated code can be wrong at enormous speed: a wrong transformation on ten records is ten fixes; on ten million, the Number of Zeros applies to the mistake too. The way I use it is step by step: clean, transform and migrate steps, with every generated command and action tracked. That’s deterministic, auditable automation, not unattended judgment. Test it at realistic scale before you trust it with production data. ⟲

Ngoài kỳ thi: AI thay đổi điều gì. AI giảm công sức xây dựng công cụ chuyển đổi, và giúp tạo và chạy các thao tác hàng loạt nhanh hơn. Thao tác càng lớn, nhu cầu về phép chuyển đổi tất định, các bước được theo dõi, diễn tập, kiểm soát và đối chiếu càng mạnh.

  • Cơ chế tải và phiên bản API nào phù hợp với khối lượng và hình dạng của công việc, thay vì đối xử với một đợt chuyển đổi như lưu lượng giao dịch.
  • Trình tự đối tượng và quan hệ theo phụ thuộc, kể cả khi nào bản ghi và quan hệ cần các lượt riêng.
  • Which operation each set of records gets (insert, update or upsert), based on what the preparation data store knows already exists. ⟲
  • Where parallel processing is safe, and where concentration, locking or automation justify sorting by parent, a model change, or serial processing. ⟲
  • Những khóa ổn định, danh tính chuyển đổi, quyền sở hữu bản ghi và công cụ lặp lại được nào làm cho các lần diễn tập và lần tải production trở nên tất định.
  • How results and new IDs come back, so loads can run in phases, retry only failures, and reload safely. ⟲
  • Bằng chứng, phân loại lỗi và diễn tập toàn bộ lượt chạy nào là bắt buộc trước khi tin tưởng quy trình ở quy mô production.

The loading dock moves enormous amounts of data. It doesn’t decide which truck unloads first, where the pallets go, which shipment belongs to which customer, what happens to a damaged pallet, whether two forklifts are using the same aisle, or whether everything that should have arrived did. That’s architecture. Know the Number of Zeros and the shape behind them. Load in dependency order, use stable keys, control concurrency, bring the keys back, make the process repeatable, keep the evidence, and rehearse the whole thing. Then use the loading dock as fast as the architecture safely allows. ⟲