CHƯƠNG 20 · Final Production Challenge•BÀI 77 / 80

Transactional Outbox và idempotent processing

Giải quyết dual-write mất event bằng Postgres transaction.

Tổng kết◷ 4 phút đọc1/4 trong chương

Nắm bản chất

Ghi jobs row và outbox row trong cùng PostgreSQL transaction bảo đảm yêu cầu publish tồn tại nếu job đã commit. Publisher dùng SELECT ... FOR UPDATE SKIP LOCKED để xử lý outbox; gửi Redis XADD rồi đánh dấu published. Worker dùng XREADGROUP, commit DB và XACK.

Vẫn có cửa sổ publish trùng nếu Publisher crash sau XADD nhưng trước commit. Worker có thể nhận messages cũ qua XAUTOCLAIM. Vì thế thiết kế là at-least-once; idempotency trên trạng thái job chỉ giải quyết tác dụng phụ trong phạm vi lab, không tự bảo vệ email/thanh toán thật.

Luồng hoạt động

API→jobs+outbox→Publisher→Redis→Worker

Hãy tự giải thích mỗi mũi tên: dữ liệu, quyền hoặc tín hiệu nào được truyền qua bước này?

Lệnh & cấu hình mẫu

BEGIN;
INSERT INTO jobs (id, status) VALUES ($1, 'queued');
INSERT INTO outbox (job_id) VALUES ($1);
COMMIT;

SELECT id, job_id FROM outbox WHERE published_at IS NULL
FOR UPDATE SKIP LOCKED LIMIT 10;

Lệnh có placeholder hoặc phụ thuộc môi trường thì cần thay thông tin thực tế, kiểm tra quyền và chỉ thực hiện trên tài nguyên được phép.

Bài tập 10–20 phút

✳

Chạy Compose Buổi 20, dừng Redis, gửi job HTTP 202, quan sát outbox backlog; phục hồi Redis và xác minh job Completed.

Lỗi dễ mắc

!

Outbox không tự bảo đảm Redis persistent sau mất toàn bộ queue; cần reconciliation chiến lược hoặc durable messaging design tương ứng.

Tự kiểm tra

Vì sao Outbox không bảo đảm exactly-once delivery?Xem đáp án ↗

Vì Postgres commit và Redis XADD chưa là một transaction chung; failure window có thể phát hành cùng event nhiều lần.

TÀI NGUYÊN ĐI KÈM

Học thêm qua lab

Có project thực hành đúng với chương này, kèm README và những giới hạn môi trường cần lưu ý.

↓ Tải mã nguồn thực hành chương 20
NGUỒN CHÍNH THỨC

Đối chiếu tài liệu gốc

Cú pháp và khả năng hỗ trợ có thể thay đổi theo phiên bản. Trước khi dùng Production, hãy kiểm tra tài liệu tương ứng.

Mở tài liệu chính thức ↗