✅ Checkpoint: Capstone service ngân hàng

By Everwise Intern

Quiz

  1. Trong kiến trúc ba layer của service ngân hàng (handler, service, repository), layer nào là nơi duy nhất được phép nói chuyện với database?
    • Service
    • Repository
    • AppState
    • Handler
  2. Vì sao AppState trong axum phải implement Clone và bên trong thường bọc Arc?
    • Vì Arc bắt buộc để dùng được extractor Json
    • Vì nếu không Clone thì router không compile được route /health
    • Vì Arc giúp serialize state thành JSON tự động
    • Vì axum clone state cho mỗi request, nên cần clone rẻ qua Arc
  3. Đoạn code sau trong handler chuyển tiền vi phạm layer ở điểm nào rõ nhất? async fn transfer(State(s): State<AppState>, Json(req): Json<TransferReq>) -> StatusCode { let from = s.db.query("SELECT * FROM accounts WHERE id = $1", &[&req.from]).await; if from.balance < req.amount { return StatusCode::BAD_REQUEST; } StatusCode::OK }
    • Handler gọi thẳng database và chứa business rule kiểm tra số dư, đồng thời trả StatusCode trơn
    • Handler dùng extractor Json thay vì tự parse body
    • Handler nhận State<AppState> thay vì tự tạo AppState
    • Handler trả về StatusCode thay vì String
  4. Vì sao phải claim idempotency key bên trong cùng transaction với việc trừ tiền, thay vì ghi key trước khi gọi pool.begin()?
    • Vì nếu ghi key ngoài transaction, giao dịch rollback sẽ để lại key khiến retry bị coi là duplicate và tiền không bao giờ chuyển
    • Vì ghi ngoài transaction khiến request_hash không được lưu
    • Vì ghi ngoài transaction làm key bị trùng giữa các request song song
    • Vì PostgreSQL không cho INSERT ngoài transaction
  5. Câu UPDATE nào chống overdraft đúng cách khi nhiều request chuyển tiền chạy song song?
    • UPDATE accounts SET balance_minor = balance_minor - $1 WHERE id = $2 AND balance_minor >= $1, rồi kiểm tra rows_affected
    • SELECT balance_minor ... FOR UPDATE, kiểm tra, rồi UPDATE trong cùng transaction
    • UPDATE accounts SET balance_minor = balance_minor - $1 WHERE id = $2, rồi kiểm tra số dư sau khi trừ
    • SELECT balance_minor FROM accounts WHERE id = $1, kiểm tra trong code, rồi UPDATE
  6. Khi một Transaction của sqlx bị drop mà chưa gọi commit, chuyện gì xảy ra?
    • Chương trình panic
    • Transaction được commit một nửa
    • Connection bị treo vĩnh viễn trong pool
    • sqlx tự rollback transaction đó
  7. Build trên CI không có DATABASE_URL nhưng vẫn dùng macro sqlx::query!. Cách xử lý chuẩn là gì?
    • Đổi hết query! sang query() để không cần kiểm tra kiểu
    • Trỏ CI vào database production để macro kiểm tra kiểu
    • Đặt DATABASE_URL rỗng trong CI
    • Chạy cargo sqlx prepare ở local, commit thư mục .sqlx và đặt SQLX_OFFLINE=true trên CI
  8. Để chống trừ tiền hai lần khi client retry, mỗi request chuyển tiền phải mang theo một ____ duy nhất, được claim trong cùng transaction với việc trừ tiền.
  9. Thuộc tính ____ tạo database riêng cho từng integration test và chạy migrations trước khi test bắt đầu.
  10. Hãy tự đánh giá mức độ hoàn thiện của capstone service ngân hàng của bạn dựa trên các tiêu chí nghiệm thu của module.

Sign in to submit answers.