🟡 Trung cấp · Bài 8 / 14

Nhất quán dữ liệu: ACID/BASE, CAP, Transactions

Những đánh đổi cốt lõi khi giữ dữ liệu nhất quán trong hệ phân tán — chủ đề "kinh điển" của mọi buổi phỏng vấn system design.

ACID vs BASE

ACID (thường ở SQL)BASE (thường ở NoSQL)
Atomic — tất cả thành công hoặc rollback hết.Basic Availability — phần lớn thời gian hoạt động.
Consistent — DB luôn hợp lệ sau transaction.Soft-state — trạng thái có thể chưa nhất quán.
Isolated — các transaction không tranh chấp.Eventual consistency — cuối cùng sẽ nhất quán.
Durable — đã commit thì tồn tại kể cả khi sự cố.(read vẫn được dù có thể trả dữ liệu cũ)
ℹ️ Đánh đổi

ACID = nhất quán mạnh, đơn giản cho lập trình viên (hợp khi dữ liệu phải tin cậy tuyệt đối, vd ngân hàng). BASE = nhất quán cuối cùng, đổi lấy scale & resilience (nhưng dev phải cẩn thận hơn). Không có đáp án đúng tuyệt đối — chọn theo yêu cầu.

Định lý CAP ⭐

Một hệ phân tán chỉ đạt được 2 trong 3: Consistency, Availability, Partition tolerance.

  • Consistency: mọi client thấy cùng dữ liệu tại cùng thời điểm, bất kể nối tới node nào.
  • Availability: mọi request đều nhận phản hồi, kể cả khi vài node chết.
  • Partition tolerance: hệ thống vẫn chạy dù mạng bị chia cắt / mất gói.
⚠️ Thực tế: phải chọn P

Mạng không bao giờ đáng tin tuyệt đối → hệ phân tán buộc phải chọn Partition tolerance (P). Điều này biến CAP thành đánh đổi giữa C và A.

LoạiĐạtKhi có partitionVí dụ
CAConsistency + AvailabilityKhông hoạt động được nếu có partitionPostgreSQL, MariaDB
CPConsistency + Partition tol.Tắt node không nhất quán đến khi sửa xongMongoDB, HBase
APAvailability + Partition tol.Vẫn phục vụ (có thể trả dữ liệu cũ), sync lại sauCassandra, CouchDB
Định lý CAP
Định lý CAP — chỉ đạt được 2 trong 3: Consistency, Availability, Partition tolerance

Định lý PACELC

Mở rộng của CAP (do Daniel J. Abadi): nếu Partition (P) → chọn A hoặc C; Else (E, lúc bình thường) → chọn Latency (L) hoặc Consistency (C).

P → A hoặc C E → L hoặc C

PACELC bổ sung điều CAP thiếu: độ trễ (latency). Vì theo CAP, một DB trả lời sau 30 ngày vẫn tính là "available" — vô lý với thực tế.

Định lý PACELC
PACELC — nếu Partition thì A/C; ngược lại (Else) thì Latency/Consistency

Transactions

Một transaction là chuỗi thao tác coi như một đơn vị công việc — tất cả thành công hoặc thất bại. Các trạng thái:

Active → Partially Committed → Committed → Terminated ↓ Failed → Aborted (rollback) → (restart hoặc kill)
Các trạng thái của transaction
Vòng đời các trạng thái của một transaction

Distributed Transactions

Thao tác trên ≥2 database, cần phối hợp commit/rollback như một đơn vị: tất cả commit, hoặc tất cả abort.

Kỹ thuậtCách hoạt động
2PC (Two-Phase Commit)Coordinator điều phối: (1) Prepare — thu thập đồng thuận; (2) Commit — nếu mọi node "prepared" thì commit, ngược lại rollback. Nhược: là blocking, coordinator chết thì kẹt.
3PC (Three-Phase Commit)Thêm pha Pre-commit giữa Prepare & Commit → mỗi pha có thể timeout, giảm vấn đề blocking của 2PC.
SagaChuỗi local transaction; mỗi cái phát event kích hoạt cái tiếp theo. Nếu lỗi → chạy compensating transaction để hoàn tác. Phối hợp qua Choreography (event) hoặc Orchestration (điều phối viên).
Two-Phase Commit
2PC — Prepare → Commit, có coordinator điều phối
Three-Phase Commit
3PC — thêm pha Pre-commit để giảm blocking
Saga pattern
Saga — chuỗi local transaction + compensating transaction khi lỗi
🚨 Saga khó ở đâu?

Khó debug, dễ phụ thuộc vòng (cyclic), thiếu cô lập dữ liệu (durability challenges), khó test (phải chạy tất cả service). Nhưng Saga là lựa chọn phổ biến cho transaction qua nhiều microservice (xem Bài 9 & 11).

✅ Tóm tắt bài 8

ACID (nhất quán mạnh, SQL) vs BASE (nhất quán cuối, NoSQL). CAP: chọn 2/3, thực tế phải có P → đánh đổi C vs A (CP vs AP). PACELC thêm yếu tố latency. Distributed transaction: 2PC (blocking), 3PC (thêm pre-commit), Saga (local tx + compensating).