Bị request nhiều lần lên server
-
Chào các bác. Em đang rất đau đầu về vấn đề này.
Em có viết 1 api. Api này cho người dùng lấy thẻ 1 lần/ngày/người. Nhưng em thấy có trường hợp db lưu 2 bản ghi thậm chí là 3, 4 bản ghi.
Em có test thử lại thì vẫn bình thường, nhưng có 1 lần mạng em yếu thế là nó tự động request 2 phátBác nào có kinh nghiệm cho em lời khuyên ạ
Dưới đây là code của em ạ
async.waterfall([ function(callback) { Setting.find({name: {$in: ['allow_charging', 'max_cashout']}}, function(err, data) { var objSetting = {}; for(var i in data) { objSetting[data[i]._doc.name] = parseInt(data[i]._doc.value); } return callback(null, objSetting); }) }, function(setting, callback) { Cashout.aggregate([ { $match: { 'user.facebook_id': user_info.facebook_id, created_at: { $gt: new Date(_start), $lt: new Date(_end) } } }, { $group: { _id: '', total: {$sum: "$card_value"} } } ], function(err, data) { var charging = 0; if(!data || data.length == 0) { charging = 0 } else { charging = data[0].total; } //Tong so tien da doi var remaning = parseInt(setting.max_cashout) - charging; //Neu tong so tien da doi ma nho hon so tien duoc config thi var dataCallback = {max_cashout: setting.max_cashout}; if(remaning >= parseInt(setting.max_cashout)) { dataCallback.status = true; return callback(0, dataCallback);//false khong cho lay the nua } dataCallback.status = false; return callback(0, dataCallback)//Cho phep lay the nhung phai check so tien doi }) }, function(infoCharging, callback) { if(infoCharging.status == false || card_value > infoCharging.max_cashout) { return callback(50); } User.findOne({_id: user_info._id}, function(err, user) { if(err || !user) { return callback(11); } //Kiem tra nguoi dung da xac nhan sdt chua if(user.phone_number == '0') { return callback(52); } //... Lay thong tin the }) } ], function(err, results) { if(err) { return res.json({ errorCode: err, data: null }) } return res.json(results) })
-
Đại khái flow ứng dụng của bạn là :
- Lấy setting -> check info người dùng -> logic trả thẻ -> cập nhật lại
Như vậy trong tính huống nào đó sẽ có các request tới mà vẫn chưa có cập nhật lại => nhiều hơn 1 bản ghi.
Cách dễ nhất là chuyển qua dùng Postgres hoặc MySQL , SQL có hỗ trợ transactions nó xử lý concurrency đơn giản. Mongo nó chỉ hỗ trợ transaction-like (Cái này mình chưa dùng bao giờ :D).Một giải pháp khác là xây dựng hệ thống dưới dạng event sourcing: Bạn sẽ không lưu dưới dạng trạng thái đã lấy hay chưa nữa ( State) mà lưu các action của người dùng. Mỗi lần lấy rồi thì 1 bản ghi và dựa vào các bản ghi này để lấy ra trạng thái.