2. 18:14 12/08/2026
Đáp án được người đặt câu hỏi chọn
Chào bạn Quốc Hùng,
Hãy xác định invariant trước: ví dụ tồn kho không âm, mỗi payment event chỉ được ghi một lần, order không được trả về thành công nếu chưa giữ được tồn kho. Sau đó đặt các thao tác database cần cùng thành công trong một transaction ngắn, dùng InnoDB và commit chỉ khi mọi kiểm tra/ghi dữ liệu đã hoàn tất.
Gợi ý thực tế:
1. Đọc và cập nhật tồn kho bằng câu lệnh có điều kiện hoặc SELECT ... FOR UPDATE trong transaction, tùy mô hình dữ liệu. Không đọc tồn kho ở một request rồi trừ ở request khác mà không có bảo vệ đồng thời.
2. Truy cập nhiều bảng/row theo một thứ tự nhất quán để giảm deadlock. Transaction càng ngắn, càng ít I/O bên ngoài thì càng tốt.
3. Deadlock vẫn có thể xảy ra. Bắt lỗi deadlock/serialization ở tầng phù hợp, retry một số lần có backoff ngắn cho thao tác idempotent, đồng thời log đủ ngữ cảnh để điều tra.
4. Không gửi email hay gọi payment provider khi database transaction còn mở. Dùng outbox: ghi event cần gửi cùng transaction, rồi worker xử lý sau commit với idempotency key.
5. Kiểm thử song song bằng nhiều request và xác minh sau cùng rằng tồn kho, order, payment ledger đều nhất quán.
Không nên tắt deadlock detection hay tăng timeout để che vấn đề. Deadlock là tín hiệu để cải thiện thứ tự lock, phạm vi transaction và logic retry.
Tham khảo: MySQL InnoDB transaction management và deadlocks documentation.
0