问题描述
我将 Angular 用作前端,将 Node.js 用作后端,同时使用 knex.js sql构建器和 Postgresql 。 我正在构建Web应用程序,用户可以在其中进行约会。 如果用户1进行了某些约会,例如在10:00,则用户2无法进行相同的约会。
我正在使用setInterval()
每三秒钟获取一次可用的小时约会,但是问题在于,如果用户#1在10:00进行约会,而用户#2在同一时间也进行了约会10:00,然后他们都在10:00约会。三秒钟后,创建的约会将对用户#2不可用,但是如何保证用户#2在经过三秒钟之后不会与用户#1同时单击“进行约会”按钮?
我该如何处理?
角度
setInterval(() => {
this.getAvailableHourAppointments();
},3000);
getAvailableHourAppointments() {
console.log('available called');
this.appointmentService.getAvailableAppointmentHours(this.user.id,this.selected_appointment_date).subscribe(availavable_appointment_hours => {
console.log('available',availavable_appointment_hours);
this.availavable_appointment_hours = availavable_appointment_hours;
})
}
Node.js
router.get('/available/:selected_appointment_date',(req,res) => {
appointment.getAllAppointments().then(all_appointments => {
all_appointments = all_appointments.filter(appointment => appointment.appointment_date == req.params.selected_appointment_date);
const appointment_hours = appointment.getAppointmentHours();
let availavable_appointment_hours = appointment_hours.filter(a => !all_appointments.some(b => a.value === b.appointment_hour));
res.json(availavable_appointment_hours)
})
})
Knex.js
function getAllAppointments() {
return db.select('*').from('appointment');
}
编辑我尝试过的MUTEX
router.post("make-appointment",res) => {
let user = req.body;
user['id'] = helpers.generateUuid();
appointment.sendMail(user,info => {
// console.log(`The mail has beed send ? and the id is ${info.messageId}`);
// res.send(info);
res.send([user]);
appointment.postAppointment(user).then(app => {
console.log(app);
let locks = new Map();
// console.log(user.id);
if (!locks.has(user.id)) {
console.log(1111);
locks.set(user.id,new Mutex());
}
locks
.get(user['id'])
.acquire()
.then(async (release) => {
try {
const existAppoinment = await appointment.getAppointmentById(app.appId).then(x => {
console.log(x);
if (x.length == 0) {
appointment.postAppointment(req.body).then(data => {
res.json(data);
}).catch(err => res.json(err));
}
}).catch(err => {
console.log(err);
})
} catch (error) {
console.log(errror);
} finally {
console.log('FINALLY CALED')
release();
}
},);
})
},err => {
// console.log('err',err);
});
});
解决方法
这是互斥问题,您必须在后端(Node.js应用)中处理。 Node中有一些软件包,例如Mutex,它实现了用于同步JavaScript中异步操作的原语。 因此,您必须“使用互斥量在NodeJS中处理互斥” ,这是对您有帮助的文章:Handle Race Conditions In NodeJS Using Mutex
以下是使用 mutex 创建锁的示例:
import { Mutex,MutexInterface } from 'async-mutex';
class PaymentService {
private locks : Map<string,MutexInterface>;
constructor() {
this.locks = new Map();
}
public async participateInFreeEvent(user: User,eventId: number): Promise<void> {
if (!this.locks.has(user.id)) {
this.locks.set(user.id,new Mutex());
}
this.locks
.get(user.id)
.acquire()
.then(async (release) => {
try {
const existOrder = await findOrder(eventId,user.id);
if (!existOrder) {
const order = buildNewOrder(eventId,user.id);
createOrder(order.id,eventId,user.id);
}
} catch (error) {
} finally {
release();
}
},);
}
}