Bỏ qua để đến nội dung
Knowledge Hub

Ghép cặp: chọn lock hay isolation cho từng tình huống Trung cấp

Thời gian đọc ước tính: 1 phút

Tám tình huống ghi đồng thời, tám cách xử lý. Phần lớn đều “chạy được” ở nhiều tình huống; câu hỏi là cách nào đúng nghĩa nghiệp vụ và rẻ nhất.

Sai thì game giải thích vì sao lựa chọn đó gần đúng nhưng không phải. Cặp hay nhầm nhất: FOR UPDATE với atomic UPDATE, SKIP LOCKED với NOWAIT, và FOR UPDATE với SERIALIZABLE khi invariant nằm trên nhiều row.

Ghép cặp

Tình huống này cần lock hay isolation nào?

Tám tình huống ghi đồng thời trên PostgreSQL 17, mặc định Read Committed. Kéo cách xử lý phù hợp nhất vào từng tình huống.

Mẹo: hỏi lần lượt "điều kiện viết được trong một câu SQL không?", "có constraint nào cưỡng chế được không?", rồi mới tới lock và isolation.

Chạm Chọn đáp án ở từng tình huống. Trên máy tính có thể kéo thẻ bên dưới thả vào tình huống.

Đã giải 0/8 · sai 0 lần

1Trừ tồn kho khi đặt hàng. 50 request tranh 10 sản phẩm cùng lúc. Quy tắc duy nhất: không được âm kho.

SELECT stock FROM product WHERE id = $1;   -- app: if (stock >= 1)
UPDATE product SET stock = $2 WHERE id = $1;

28 worker lấy job gửi email từ bảng jobs. Mỗi job độc lập. Hiện tại worker thứ hai đứng chờ job worker đầu đang khoá, dù queue còn 3.000 job.

3Đặt ghế 42. Trước khi ghi, app phải đọc trạng thái ghế, kiểm tra hạng thành viên và hạn mức vé của user, tính giá theo khung giờ, rồi mới INSERT vé và đổi trạng thái ghế.

4Payment gateway gửi webhook payment.succeeded theo kiểu at-least-once: cùng một event_id có thể đến 2–3 lần, đôi khi cùng lúc trên hai pod. Mỗi event chỉ được cộng tiền một lần.

5Quy tắc: mỗi ca phải còn ít nhất một bác sĩ trực. 5 đường code (xin nghỉ, đổi ca, admin sửa lịch, import Excel, API mobile) đều đọc nhiều row rồi ghi row khác. Hai bác sĩ cùng xin nghỉ, cả hai được duyệt.

SELECT count(*) FROM shifts WHERE shift_id = 7 AND on_call;  -- cả hai thấy 2
UPDATE shifts SET on_call = false WHERE doctor = $me;

6Biên tập viên mở form sửa bài viết, đọc và sửa 5–15 phút rồi bấm Lưu. Thỉnh thoảng hai người sửa cùng bài và người lưu sau ghi đè mất nội dung của người trước.

7Nút "Hoàn tiền" trên trang quản trị đơn. Xử lý mất ~2 giây trong transaction. Nếu nhân viên khác đang hoàn tiền cùng đơn, UI phải báo ngay "Đơn đang được xử lý" thay vì quay vòng chờ.

8Cron tính lại điểm thưởng lúc 02:00 chạy trên cả 3 pod. Job chạy 20 phút, không gắn với row nào cụ thể. Chạy hai lần là điểm bị cộng đôi.

Chơi xong, đọc Viết transaction trong code để xem bảng chọn pattern và demo 50 request tranh 10 sản phẩm.