Giải thuật lock 1 xử lý trong bất đồng bộ NodeJS?

Chào mọi người, Đây là bài post đầu tiên nên có gì mọi người góp ý với nha.

  1. Mình có thiết kế 1 con chatbot telegram để sử dụng.
  2. Trong có co inline button như hìn sau:
  3. Nếu nhiều người dùng khác nhau nhất nhanh quá nó sẽ gửi nhiều request lên hệ thống.
  4. Mình đã sáng tạo ra giải thuật lock ở 1 thời điểm chỉ 1 xử lý của 1 người.

Issue: Vẫn có trường hợp 2 người cũng nhất 1 thời điểm bị xử lý sai.

Expert: Mong mọi người góp ý về code ạ.

    // 1 phân tích callback_data 
    // Lấy mã đơn
    var res = callback_data.match(/^BOOK_ORDER_(.+)$/i);
    var code = res[1];

    /////// KHOA DON
    if (locks[code] == 1) {
      return;
    }
    locks[code] = 1;
    /////// END KHOA DON

    // lọc tình trạng 2 bạn cùng lấy đơn
    // 6 là trạng thái đơn trong box chung
    var order = await Order.get(code);
    if (order.stateorder_id != 6) {
      locks[code] = 0;
      return;
    }

    var shipper = await Shipper.get(nguoichat_id);
    if (!shipper) {
      locks[code] = 0;
      return;
    }

    // 3 Lưu lần 1 để đơn chuyển sang trạng thái đã gửi, 2 người cùng lấy đơn
    var params = {
      SET: {
        shipper_id : shipper.shipper_id,
        state_order_shipper : "Đã gửi",
        state_order_shipper_at : moment().format('YYYY-MM-DD HH:mm:ss'),
        stateorder_id : 5,
      },
      WHERE: {
        code
      }
    };
    await Model.update('orderbill', params);
    locks[code] = 0;

Cách làm của bạn nhìn thì có vẻ đúng, nhưng js xử lí sẽ vẫn bị sai business, vì lock(coi như mutex) của bạn vẫn xảy ra trường hợp >=2 background thread cùng chạy song song và tới dòng code check:

if (locks[code] == 1) {
  return;
}
locks[code] = 1;

Thì cả 2 thread cùng đóng lock, code dưới vẫn chạy.
Và việc nó get order status cùng trống là đương nhiên vì có thể bạn ?ko dùng transaction để update nên đã xảy ra trường hợp bị đè ?

Vấn đề ở đây có thể giải quyết bằng cách thêm mutex khoá/mở đúng lúc, và phải là mutex chuẩn.
Tham khảo:

2 Likes
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?