Cho mình hỏi về việc thay đổi data trong hệ thống microservice
Đối với các hệ thống ngân hàng, bạn không nên áp dụng cache và Async việc update DB. Bởi vì các giao dịch ngân hàng bắt buộc phải strong consistency. Nếu lỡ như bạn đã gửi lại thông tin cho user là chuyển tiền thành công nhưng việc update DB lỗi hoặc lỗi máy ATM thì thông tin user nhận là sai. Ngoài ra còn gặp những vấn đề liên quan tới race condition nữa. Lưu trên cache cũng gặp rủi ro nếu như redis cache sập thì dữ liệu sẽ mất hết. Cách giải quyết có thể như sau:
Bước 1: Giữ chỗ (Hold/Freeze/Authorize) - Đồng bộ (Synchronous)
- Ví dụ khi bạn bấm rút 2 triệu: Service tiếp nhận lệnh và gọi đồng bộ xuống DB.
- Hệ thống sẽ thực hiện một lệnh Lock số dư của User đó (ví dụ: SELECT balance FROM accounts WHERE id = x FOR UPDATE).
- Kiểm tra số dư. Nếu đủ, hệ thống không trừ tiền ngay, mà chuyển 2 triệu đó vào trạng thái "Hold" (Tạm giữ/Phong tỏa).
- Lúc này, số dư khả dụng (Available Balance) giảm đi 2 triệu, nhưng số dư thực tế (Current Balance) vẫn giữ nguyên. Thao tác này diễn ra bằng một Transaction trong DB cực kỳ nhanh (vài mili-giây).
Bước 2: Ra lệnh cho ATM (Synchronous) Sau khi đã Hold tiền thành công trong DB, backend trả kết quả Đồng bộ về cho ATM: "Tôi đã giữ tiền an toàn, anh hãy nhả tiền mặt cho khách đi".
Bước 3: Đẩy tiền và Hoàn tất (Settle) hoặc Hủy (Rollback)
- Kịch bản 1 (Thành công): ATM nhả tiền thành công -> ATM gửi tín hiệu Confirm về Backend -> Backend thực hiện Deduct (Trừ hẳn) 2 triệu đang bị Hold trong DB (Thao tác này có thể chạy Async hoặc Sync tùy kiến trúc kiến tạo).
- Kịch bản 2 (Thất bại/Kẹt tiền): ATM không nhả được tiền -> Gửi tín hiệu Cancel về Backend -> Backend thực hiện Unhold (Giải phóng) 2 triệu đó lại cho khách hàng.
SOS! lỡ commit API key vào repo công khai trên GitHub
https://github.com/gitleaks/gitleaks Bạn có thể thử sử dụng gitleaks nhé.
Tổ chức
Chưa có tổ chức nào.