🇬🇧 Read the English version of this article on tanhdev.com
Answer-first: Khi chuyển đổi từ Magento sang Golang, bạn có ba chiến lược cơ sở dữ liệu (database): (A) Dùng chung DB (Shared DB) để tối ưu compute ngay lập tức, (B) CDC + Outbox để tách DB dần dần mà không cần đụng vào code PHP, hoặc (C) Tách biệt hoàn toàn bằng Event Bus. Phương án A là một trạng thái chuyển giao tuyệt vời nhưng lại là một trạng thái cuối cùng thảm họa. Phương án B là con đường được khuyến nghị trong ngành công nghiệp cho hầu hết các hệ thống Magento — nó cho phép Go làm chủ schema của riêng mình và làm phẳng cấu trúc EAV mà không yêu cầu PHP Magento phải phát ra dù chỉ một sự kiện nào. Phương án C chỉ khả thi khi đội ngũ Magento của bạn có thể xây dựng và duy trì một hệ thống phát hành sự kiện (event publisher) đáng tin cậy.
Những gì bạn sẽ học được mà AI không nói cho bạn
- Tại sao Go chạy trên MySQL của Magento lại nhanh hơn ở tầng compute nhưng vẫn bị nghẽn cổ chai ở tầng truy vấn EAV — và cách giải quyết thực sự là gì.
- Yếu tố quyết định duy nhất giữa CDC (Phương án B) và Event Bus (Phương án C): ai sở hữu mã nguồn PHP Magento.
Tình thế tiến thoái lưỡng nan của Strangler Fig: Compute vs. Data
Khi chuyển đổi từ khối nguyên khối (monolith) Magento sang backend Golang, các kiến trúc sư phải đối mặt với một quyết định không hề rõ ràng: chúng ta nên chuyển đổi tầng API và cơ sở dữ liệu cùng một lúc không?
Chuyển đổi cả hai đồng thời đòi hỏi phải thiết lập Tính nhất quán cuối (Eventual Consistency), Ghi kép (Dual-Writes), và mô hình Saga ngay từ Ngày 1. Điều này làm chậm thời gian ra mắt (time-to-market) và ngăn doanh nghiệp nhìn thấy sự cải thiện hiệu năng trong 9–18 tháng.
Sự thay thế là Shared Database Quick Win (Thắng nhanh nhờ dùng chung DB) — chuyển đổi tầng compute API trước, giữ nguyên tầng dữ liệu, và câu giờ để thiết kế một chiến lược tách DB chuẩn chỉnh.
Nhưng “câu giờ” chỉ hiệu quả nếu bạn có một kế hoạch rõ ràng cho Giai đoạn 2 (Phase 2). Bài viết này định nghĩa cả ba phương án và cung cấp cho bạn một bộ khung ra quyết định để chọn đúng con đường.
Ba Phương án trên Bàn đàm phán
┌──────────────────┬──────────────────────────┬──────────────────────────┐
│ PHƯƠNG ÁN A │ PHƯƠNG ÁN B │ PHƯƠNG ÁN C │
│ Shared DB │ Evolutionary CDC │ Full Separation + │
│ (Thắng nhanh) │ (Debezium + Outbox) │ Event Bus (Kafka) │
├──────────────────┼──────────────────────────┼──────────────────────────┤
│ Go đọc chung │ Go làm chủ write DB. │ Tách riêng hoàn toàn DB.│
│ MySQL của │ CDC đồng bộ reads từ │ Giao tiếp qua Kafka. │
│ Magento trực tiếp│ Magento. Không sửa PHP. │ Magento phát ra sự kiện │
└──────────────────┴──────────────────────────┴──────────────────────────┘
Phương án A — Shared Database (Thắng nhanh)
┌──────────────┐ ┌──────────────────────────────┐
│ Go (magento-go) │──READ──▶│ │
│ │──WRITE─▶│ MySQL Magento (dùng chung) │
│ PHP Magento │──READ──▶│ │
│ │──WRITE─▶└──────────────────────────────┘
└──────────────┘
Trong Giai đoạn 1 của mô hình Strangler Fig, bạn đưa một smart router (ví dụ: shadow proxy routemode) vào trước Magento, sau đó viết lại các API có lưu lượng truy cập cao bằng Go — nhưng kết nối Go trực tiếp vào MySQL hiện tại của Magento.
Tại sao nó hiệu quả (Lợi ích ngay lập tức)
Magento PHP có thể mất 100–200ms chỉ để khởi động framework trước khi thực thi bất kỳ câu lệnh SQL nào. Go loại bỏ hoàn toàn sự cồng kềnh này. Được đo lường trong một dự án chuyển đổi Magento→Go thực tế (mag-go), cùng một endpoint xác thực (authentication) đã giảm từ 180ms xuống còn 8ms — giảm tới 22 lần — mà không hề thay đổi câu truy vấn cơ sở dữ liệu nào.
- Tách biệt Compute ngay lập tức. Sự cồng kềnh của PHP framework (DI container, ORM hydration, module observers) hoàn toàn biến mất.
- Không có vấn đề đồng bộ dữ liệu. Cả hai hệ thống cùng đọc các bản ghi đã commit trên MySQL — không có độ trễ của tính nhất quán cuối.
- Rollback cực dễ. Chỉ một thay đổi cấu hình trong
routemodelà có thể lật luồng traffic quay về PHP.
Mặt tối — Tại sao đây không thể là trạng thái cuối cùng
Mặt tối 1: Magento DB là một “API ẩn” mà bạn không kiểm soát
Schema của Magento không phải là API của bạn — nhưng Go giờ đây lại bị gắn chặt vào nó như thể nó là API.
Nâng cấp Magento 2.4.6 → 2.4.7
→ Đổi tên cột trong bảng customer_entity
→ Go struct binding âm thầm gặp lỗi hoặc panic
→ Gây ra sự cố lúc 2h sáng
Adobe đã ngừng hỗ trợ tính năng “split database” trong Magento 2.4.6+. Mỗi bản nâng cấp lại càng gom chung schema lại với nhau. Mỗi struct trong Go trỏ tới một bảng của Magento là một phụ thuộc không được khai báo và không có SLA (cam kết chất lượng dịch vụ).
Mặt tối 2: Xung đột Ghi (Write Conflict) — Race Conditions trên các bảng dùng chung
| Bảng (Table) | PHP ghi | Go ghi | Mức độ Rủi ro |
|---|---|---|---|
customer_entity | ✅ | ✅ (cập nhật token, địa chỉ) | CAO (HIGH) |
oauth_token | ✅ | ✅ (magento-go auth module) | NGHIÊM TRỌNG (CRITICAL) |
customer_address_entity | ✅ | ✅ | CAO (HIGH) |
quote / sales_order | ✅ | Chỉ qua Proxy | Trung bình (Medium) |
Các cơ chế khóa cấp dòng (row-level locks) của MySQL ngăn chặn việc đọc sai (dirty reads) nhưng không ngăn chặn được các xung đột logic nghiệp vụ. Nếu Go cập nhật token session của khách hàng cùng lúc Magento làm vô hiệu hóa nó, kết quả là trạng thái xác thực bị hỏng — chứ không phải lỗi database.
Mặt tối 3: Cạm bẫy Distributed Monolith (Nguyên khối Phân tán)
Go service ───────▶ Shared MySQL ◀─────── PHP Magento
↑ ↑
"microservice" sự gắn kết nguyên khối trên thực tế
Giờ đây bạn có hai runtime riêng biệt nhưng cùng một miền thất bại (failure domain). Một câu truy vấn Go quét toàn bộ bảng (full-scan) catalog_product_entity_varchar có thể làm suy giảm hiệu năng thanh toán (checkout) của Magento. Về mặt kiến trúc, hệ thống này giống hệt một hệ thống nguyên khối (monolith) — chỉ là khó debug hơn vì dính líu đến hai codebase.
Mặt tối 4: EAV mới là Cổ chai thực sự — Go không giải quyết được điều đó
-- Chỉ để tải một khách hàng kèm tất cả thuộc tính EAV:
SELECT ce.*,
cevs.value AS first_name, -- customer_entity_varchar (JOIN 1)
cevi.value AS store_id, -- customer_entity_int (JOIN 2)
...
FROM customer_entity ce
JOIN customer_entity_varchar cevs ON ce.entity_id = cevs.entity_id
JOIN customer_entity_int cevi ON ce.entity_id = cevi.entity_id
... -- Tổng cộng 5–10 JOINs
Go thực thi câu truy vấn này nhanh hơn PHP, nhưng kế hoạch thực thi truy vấn (query plan) là hoàn toàn giống nhau. Điểm nghẽn là ở thiết kế schema EAV, không phải ở ngôn ngữ lập trình. Cách duy nhất để sửa là làm phẳng (flatten) EAV thành một schema riêng do Go làm chủ — điều này đòi hỏi phải tách biệt DB.
Cách thực thi Phương án A an toàn (Các ràng buộc không thể thương lượng)
Nếu bạn cam kết chọn Phương án A như một trạng thái chuyển giao:
- Ràng buộc chỉ-đọc (Read-only): Go chỉ được phép
SELECTtrên các bảng thuộc sở hữu của Magento. Mọi hành động ghi (write) phải được proxy trả về API PHP của Magento. - Chính sách sở hữu bảng: Tài liệu hóa các bảng mà Go được phép đọc. Không được phép có những hành vi đọc không được ghi nhận.
- Kiểm tra Schema pinning CI: Chạy so sánh (diff) schema trên mỗi PR nâng cấp Magento. Nếu một cột thay đổi mà Go có tham chiếu đến, hãy chặn build ngay.
- Đặt thời hạn cứng cho Giai đoạn 2: Phương án A mà không có ngày triển khai Giai đoạn 2 trên lịch trình thì chắc chắn sẽ trở thành giải pháp vĩnh viễn do sức ỳ.
Phương án B — Evolutionary CDC + Outbox (Con đường được khuyến nghị)
┌──────────────┐ ┌──────────────────┐
│ PHP Magento │──WRITE──────▶│ MySQL Magento │
└──────────────┘ │ (master) │
└────────┬─────────┘
│ binlog (không cần sửa PHP)
▼
┌──────────────┐
│ Debezium │ ← đọc binlog trực tiếp
│ CDC Engine │
└──────┬───────┘
│ stream events
▼
┌──────────────┐ WRITE-OWNED ┌────────────────────────┐
│ Go (magento-go) │──────────────▶│ Go DB (tách biệt) │
│ │ READ-SYNCED │ Schema phẳng │
│ │◀──────────────│ token, session, │
└──────────────┘ │ customer_flat... │
│ └────────────────────────┘
│ Outbox events (Go → Magento nếu cần)
▼
┌──────────┐
│ Kafka │──▶ Magento consumer
└──────────┘
Một góc nhìn cốt lõi: Debezium đọc trực tiếp binary log (binlog) của MySQL. Điều này có nghĩa là bạn không bao giờ cần sửa đổi một dòng code PHP Magento nào để stream mọi thay đổi dữ liệu vào database của Go.
Cách thức hoạt động của CDC + Outbox
Bước 1 — Go tạo DB riêng cho dữ liệu mà nó làm chủ:
-- Bảng do Go làm chủ (Go ghi vào đây, Magento không bao giờ chạm tới)
CREATE TABLE magento_customer_token (
id UUID PRIMARY KEY,
customer_id BIGINT NOT NULL,
token_hash VARCHAR(255) NOT NULL,
expires_at TIMESTAMP NOT NULL
);
CREATE TABLE magento_outbox (
id UUID PRIMARY KEY,
event_type VARCHAR(100) NOT NULL,
payload JSONB NOT NULL,
created_at TIMESTAMP DEFAULT now(),
published_at TIMESTAMP
);
Bước 2 — Debezium stream các thay đổi của Magento → Go DB:
# debezium-connector.yaml
connector.class: io.debezium.connector.mysql.MySqlConnector
database.hostname: magento-mysql-master
database.include.list: magento
table.include.list: magento.customer_entity, magento.catalog_product_entity
# Debezium đọc binlog — không cần sửa PHP Magento
Bước 3 — Các lệnh ghi (write) của Go sử dụng Outbox Pattern (Nguyên tử):
// Trong một DB transaction duy nhất — không có rủi ro dual-write
tx.Exec(`INSERT INTO magento_customer_token (...) VALUES (...)`)
tx.Exec(`INSERT INTO magento_outbox (event_type, payload)
VALUES ('TOKEN_CREATED', $1)`, tokenPayload)
// OutboxProcessor xuất bản (publish) lên Kafka mỗi 500ms
// Debezium bắt lấy dòng outbox → định tuyến về Magento nếu cần
Tại sao Phương án B lại chiến thắng đối với hầu hết các đội ngũ
| Những gì bạn đạt được | Những gì bạn tránh được |
|---|---|
| Go làm chủ schema của nó — flatten EAV → tốc độ đọc nhanh gấp 5 lần | Không bao giờ phải chạm vào code PHP Magento |
| Ghi ACID (an toàn) trên Go DB của riêng nó | Không có độ phức tạp của Saga ở Ngày 1 |
| Debezium stream các thay đổi của Magento về Go | Không có rủi ro chạy đua khi ghi kép (dual-write race conditions) |
| Triển khai theo từng domain (Auth trước, Checkout sau cùng) | Không phải đối mặt với rủi ro Big Bang cutover |
Phương án C — Tách riêng hoàn toàn DB + Event Bus
┌─────────────────────────────────────────────────────────────┐
│ EVENT BUS (Kafka) │
│ topic: customer.updated │ order.created │ inventory.changed │
└──────────┬───────────────────────────────┬──────────────────┘
│ PUBLISH │ CONSUME
▼ ▼
┌──────────────────┐ ┌───────────────────────────────┐
│ PHP Magento │ │ Go Service (magento-go) │
│ │ │ │
│ MySQL Magento │ │ Go DB (sở hữu riêng, schema phẳng)│
│ (sở hữu hoàn toàn)│ │ CQRS read projections │
│ │ │ customer_flat, order_summary │
│ ← Magento phải │ │ │
│ phát ra TẤT CẢ│ └───────────────────────────────┘
│ sự thay đổi │ │ PUBLISH
│ trạng thái │◀────────────────────────┘
│ như là sự kiện│ (các sự kiện bù đắp / compensating events)
└──────────────────┘
Ở Phương án C, cả hai hệ thống được cô lập hoàn toàn. Việc giao tiếp diễn ra hoàn toàn thông qua event bus. Mỗi dịch vụ sở hữu toàn bộ cơ sở dữ liệu của chính nó.
Những gì Phương án C đòi hỏi mà Phương án B thì không
Khác biệt cốt lõi nằm ở chỗ ai là người xuất bản các sự kiện:
| Phương án B (CDC) | Phương án C (Event Bus) | |
|---|---|---|
| Ai xuất bản thay đổi? | Debezium đọc tự động binlog | PHP Magento phải ghi vào bảng outbox |
| Code PHP Magento có phải sửa? | ❌ Không yêu cầu | ✅ Bắt buộc — mỗi thay đổi trạng thái cần một sự kiện |
| Rủi ro nếu team PHP chậm chạp | Bằng 0 (CDC là hạ tầng) | Cao (Go DB sẽ bị thiếu hụt dữ liệu) |
| Độ trễ đồng bộ | 50–200ms (độ trễ binlog) | 10–100ms (nếu Kafka khỏe) |
| Replay sự kiện | Có (lịch sử binlog) | Có (Kafka retention) |
Phương án C là kiến trúc đích (target architecture) đúng đắn cho dài hạn. Nhưng nó đòi hỏi đội ngũ PHP Magento phải liên tục phát hành các sự kiện domain một cách đáng tin cậy cho mọi sự thay đổi trạng thái — cập nhật khách hàng, trạng thái đơn hàng, điều chỉnh hàng tồn kho, áp dụng khuyến mãi. Chỉ cần bỏ sót một hạng mục sự kiện, cơ sở dữ liệu của Go sẽ âm thầm lệch pha so với Magento.
Ma trận so sánh 3 chiều
| Tiêu chí | Phương án A: Shared DB | Phương án B: CDC + Outbox | Phương án C: Full Event Bus |
|---|---|---|---|
| Mô hình nhất quán | Strong ACID ✅ | ACID writes, eventual reads ⚠️ | Eventual consistency ❌ |
| Độ kết dính Schema | Chặt — Magento sở hữu ❌ | Giảm dần theo domain ⚠️ | Lỏng lẻo — event schema ✅ |
| Rủi ro xung đột ghi | Cao — race conditions ❌ | Thấp — ghi độc lập ✅ | Không có — cách ly hoàn toàn ✅ |
| Hiệu suất EAV | Không đổi ❌ | Flatten theo domain ⚠️ | Full flatten ✅ |
| Scale độc lập | Không ❌ | Một phần ⚠️ | Toàn diện ✅ |
| Rollback Go service | Dễ — lật routemode ✅ | Dễ cho mỗi domain ✅ | Khó — event schema backward compat ❌ |
| Thời gian ra Production | Đang chạy ngay ✅ | 3–6 tháng ⚠️ | 9–18 tháng ❌ |
| Sửa đổi code Magento | Không ✅ | Không (CDC reads binlog) ✅ | Bắt buộc — event publisher ❌ |
| Hạ tầng mới | Không ✅ | Debezium + Kafka ⚠️ | Kafka + Schema Registry + CQRS ❌ |
| Độ khó Debug | Thấp ✅ | Trung bình ⚠️ | Cao — trace qua nhiều trạm ❌ |
| Kỹ năng Team yêu cầu | Thấp ✅ | Trung bình ⚠️ | Cao — hệ thống phân phân tán ❌ |
| Cô lập lỗi (Fault isolation) | Không — 1 DB = tất cả sập ❌ | Một phần ⚠️ | Toàn diện ✅ |
| An toàn giao dịch Checkout | ACID ✅ | Yêu cầu Saga ⚠️ | Saga + bù đắp giao dịch ❌ |
| Rủi ro bán lố tồn kho | Không (ACID) ✅ | Thấp nếu CDC lag < 100ms ⚠️ | Cao nếu consumer lag ❌ |
| Khả năng Replay / Audit | Không ❌ | Một phần (Outbox) ⚠️ | Toàn diện (Kafka retention) ✅ |
Bảng rủi ro cho mỗi phương án
Phương án A — Các rủi ro của Shared DB
| Rủi ro | Khả năng | Tác động | Khắc phục (Mitigation) |
|---|---|---|---|
| Nâng cấp Magento làm vỡ Go struct | Cao (mỗi bản upgrade) | Service sập | Schema pinning + kiểm tra CI diff |
| Race condition khi ghi bảng auth | Trung bình | Dữ liệu hỏng | Chính sách sở hữu bảng, Go chỉ đọc |
| Cổ chai DB khi mở rộng | Cao | Hai bên đều chậm | Read replica riêng cho Go |
| Trở thành Distributed monolith vĩnh viễn | Chắc chắn nếu không có hạn chót | Nợ kiến trúc (Debt) | Đặt hạn chót rõ ràng cho Giai đoạn 2 |
Phương án B — Các rủi ro của CDC
| Rủi ro | Khả năng | Tác động | Khắc phục (Mitigation) |
|---|---|---|---|
| Lỗi đường ống CDC | Thấp (Debezium HA) | Go DB lệch đồng bộ | Giám sát độ trễ (Lag) + Cảnh báo |
| Nhận sự kiện trùng lặp | Trung bình | Ghi trùng dữ liệu | Idempotency key trên mọi consumer |
| Áp lực lưu trữ MySQL binlog | Thấp | Chi phí Storage | Chính sách lưu giữ (retention) binlog |
| Quá trình dual-write tạm thời | Trung bình | Trôi dạt dữ liệu (Drift) | Outbox pattern ngay từ ngày đầu |
Phương án C — Các rủi ro của Full Event Bus
| Rủi ro | Khả năng | Tác động | Khắc phục (Mitigation) |
|---|---|---|---|
| Magento phát thiếu sự kiện | Rất Cao | Go DB thiếu dữ liệu | Bộ Integration test, bắt buộc |
| Thay đổi Schema sự kiện | Cao (do nghiệp vụ) | Consumer sập | Schema Registry + backward compat |
| Saga lỗi → đơn hàng thiếu đồng bộ | Trung bình | Ảnh hưởng doanh thu | Dead-letter queue + xử lý thủ công |
| Bão sự kiện (Event storm) khi flash sale | Trung bình | Quá tải Kafka | Phân chia Topic + SLA độ trễ consumer |
| Độ trễ Read-your-own-write | Cao | Trải nghiệm UX tệ | Cập nhật UI theo hướng lạc quan (Optimistic) |
⚠️ Lưu ý tối quan trọng cho Phương án C: PHP Magento phải ghi vào bảng outbox nằm chung trong một database transaction với quá trình thay đổi trạng thái kinh doanh. Điều này thường bị triển khai sai — xuất bản thẳng lên Kafka sau khi DB commit sẽ tạo ra một khoảng trống ghi kép (dual-write gap). Nếu Kafka publish bị lỗi, sự kiện đó bị mất tích âm thầm và database của Go sẽ bị lệch vĩnh viễn.
Bộ khung ra quyết định (Decision Framework) — Đâu là lựa chọn đúng cho bạn?
Q1: Team của bạn có 2+ kỹ sư có kinh nghiệm về hệ thống phân tán không?
└─ KHÔNG → Ở lại Phương án A, bổ sung rào chắn (schema pinning, read-only policy)
└─ CÓ → Q2
Q2: Mức độ chịu đựng (tolerance) đối với việc bán lố hàng tồn kho của bạn có bằng 0 không?
└─ CÓ → Phương án B (CDC duy trì ACID writes, không rủi ro eventual consistency lúc ghi)
└─ KHÔNG → Cả B và C đều khả thi
Q3: Bạn có cần Go mở rộng hoàn toàn độc lập với DB của Magento không?
└─ KHÔNG → Phương án B là đủ và được khuyến nghị
└─ CÓ → Q4
Q4: Team PHP Magento có khả năng cam kết xây dựng và duy trì các event publisher không?
└─ KHÔNG → Bắt buộc chọn Phương án B (CDC không cần sửa PHP)
└─ CÓ → Phương án C khả thi (lộ trình: 12–18 tháng)
Ưu tiên Domain — Những gì cần tách biệt trước
Không phải tất cả các domain (miền nghiệp vụ) đều mang rủi ro giống nhau. Hãy di chuyển theo trình tự này bất kể bạn chọn Phương án B hay C:
| Domain | Ưu tiên | Tại sao | Rủi ro |
|---|---|---|---|
Auth / Token (auth/) | Đầu tiên | Go đã làm chủ logic token, không phụ thuộc Magento | Thấp |
OIDC (oidc/) | Đầu tiên | Thuộc hoàn toàn về Go, không cần dữ liệu Magento | Thấp |
Wishlist (wishlist/) | Thứ 2 | Domain đơn giản, lượng dữ liệu nhỏ | Thấp |
Customer read (customer/) | Thứ 2 | Làm phẳng EAV → Đọc nhanh 5×, việc ghi vẫn là proxy | Trung bình |
| Customer write | Thứ 3 | Cần có Saga với Magento để đồng bộ địa chỉ/profile | Trung bình |
Cart / Checkout (cartcheckout/) | Cuối cùng | Rủi ro kinh doanh cao nhất, cần Saga trưởng thành | Cao |
Không bao giờ di chuyển Cart/Checkout sang một DB riêng cho tới khi mô hình Saga đã được chứng minh hiệu quả trên Production ở các domain ít rủi ro hơn.
Checklist Hạ tầng trước khi Tách biệt DB
Trước khi cam kết theo Phương án B hoặc C, hãy xác thực các điều kiện tiên quyết sau:
required_before_option_b:
- mysql_binlog_enabled: true # Kiểm tra bằng: SHOW VARIABLES LIKE 'log_bin'
- debezium_or_dms: deployed # Debezium nhúng hoặc chạy riêng
- kafka_or_redis_streams: deployed # Nền tảng truyền tải sự kiện CDC
- outbox_table: created_in_go_db # Khởi tạo bảng magento_outbox
- idempotent_consumers: implemented # Consumer có logic check idempotency key
- cdc_lag_monitoring: configured # Cảnh báo nếu lag > 500ms
additional_for_option_c:
- php_event_publisher: implemented # Module Magento ghi vào outbox table
- schema_registry: deployed # Quản lý schema bằng Avro hoặc Protobuf
- saga_orchestrator: stable # Ổn định trên production cho domain nhỏ
- dead_letter_queue: configured # Dành cho compensation saga thất bại
Lộ trình Khuyến nghị (Recommended Roadmap)
0–6 tháng (BÂY GIỜ) 6–12 tháng 12–24 tháng
──────────────── ─────────── ────────────
Phương án A + Rào chắn → Phương án B: CDC Phương án B → C (dần dần)
DB Auth/OIDC trước
Chính sách Sở hữu bảng Streaming bằng Debezium Chỉ khi team PHP
Kiểm tra Schema CI Flatten EAV reads có thể phát hành events
Chạy ngầm routemode Wishlist + Customer Mô hình Saga ổn định
Chốt hạn cứng Giai đoạn 2 tách biệt việc đọc Cart/Checkout CUỐI CÙNG
Xem thêm
- Phần 6: Giai đoạn 1 — Strangler Fig: Di chuyển Read-Only + CDC — Chi tiết triển khai: Cấu hình Debezium, feature flags, code Go service
- Phần 9: Transactional Outbox + Saga Pattern — Triển khai outbox trên PostgreSQL, choreography saga, idempotency keys
- Phần 7: Giai đoạn 2 — Dual-Write với Dapr PubSub — Đồng bộ hai chiều, giải quyết xung đột, rollout bằng feature flag
- Zero-Downtime: Chuyển đổi từ Magento sang Microservices — Sổ tay thực thi toàn diện 3 giai đoạn chuyển đổi
- Chuyển đổi Magento sang Microservices: Khi nào & Tại sao — Động cơ quyết định, giới hạn EAV, checklist nên/không nên di chuyển
