我目前正在使用nodejs、sequelize、mysql和reactjs开发一个服务。
下面的代码是为一篇文章创建一个回复。
module.exports.reply = async ({
userId,
postId,
text
}) => {
const t1 = await orm.transaction({
isolationLevel: orm.Transaction.ISOLATION_LEVELS.SERIALIZABLE
});
try {
let retData = { code: 0, data: {}};
const reply = await replyModel.findOne({
where: {
userId: userId,
postId: postId
},
lock: t1.LOCK.UPDATE,
transaction: t1
});
if (reply == null) {
await replyModel.create({
postId: postId,
text: text
}, {transaction: t1});
}
retData.code = 200;
await t1.commit();
return retData;
} catch (err) {
await t1.rollback();
throw err;
}
}
上面的代码是为一篇文章创建回复的POST请求。
如果我连续点击回复按钮5~10次,就会出现死锁。
为了避免死锁,我隐藏了被点击的按钮。
但是,当回复请求发生多次时,有什么其他方法可以避免服务器端的死锁吗?
阻止禁用发布按钮 (也许还可以显示一个 "加载 "符号) 直到发布回复,这似乎是一个很好的用户体验实践。
如果你想为你的用户提供同时更新一个DB行的能力(例如,许多用户同时发布同一项目的更新),那么我会建议使用工作队列(如 BullMQ)来依次应用这些更新。