ACID Transactions và Database Locking: Chống race condition khi chuyển tiền
Hướng dẫn chống race condition và double spending trong chuyển tiền với PostgreSQL: ACID, SELECT FOR UPDATE, optimistic versioning, idempotency, deadlock, retry và kiểm thử đồng thời.

Bài toán: hai request cùng tiêu một số dư
Tài khoản A có 100.000đ. Hai request rút 80.000đ đến gần như cùng lúc:
- Request 1 đọc số dư 100.000đ và thấy đủ.
- Request 2 cũng đọc 100.000đ và thấy đủ.
- Cả hai cùng ghi số dư mới.
Nếu logic là “đọc → kiểm tra → ghi” mà không có kiểm soát đồng thời, cả hai request có thể được chấp nhận. Đây là race condition dẫn đến lost update hoặc double spending.
ACID là nền móng, nhưng chỉ bọc code bằng BEGIN và COMMIT chưa đủ. Ta còn phải chọn isolation level, chiến lược locking, constraint và cách retry phù hợp.


