Open lmk123 opened 2 years ago
事情是这样的。用户在划词翻译里可以选择付费使用翻译服务,后台里扣费的代码如下:
// 执行翻译功能的路由 router.get('/translate', async (ctx) => { const { apiName, userId } = ctx console.log('开始调用' + apiName) const user = await UserModel.findOne(userId) console.log('用户的余额为:', user.balance) // 从翻译服务那里获取翻译结果,并返回需要扣除的费用 const { result, price } = await doTranslate(apiName) console.log(`${apiName}扣除的费用为:`, price) // 从用户的余额里扣除费用 user. balance -= price console.log('用户的剩余余额为:', user.balance) // 保存进数据库 await user.save() ctx.body = result })
这段代码在生产环境运行到现在,直到我今天无意中发现一个问题:我同时开启了多个翻译服务,但只扣了一次费用。
细心的同学可能已经直到问题出在哪里了……
当用户同时启用了多个翻译服务时,客户端实际上同时发起了多个翻译请求,也就是说,控制台的日志是这样的:
开始调用有道翻译 开始调用百度翻译 用户的余额为: 100 用户的余额为: 100 百度翻译扣除的费用为:1 有道翻译扣除的费用为:1 用户的剩余余额为:99 用户的剩余余额为:99
这也就导致了为什么按照预期应该扣除 2 的场景下,最终结果却只扣除了 1……
本来以为作为一个前端来说,对于异步已经得心应手,但现在已经完全不敢有这个自信了 :joy:
哈哈,不过这也不是异步的问题,是并发的问题(“并发扣费”),任何语言都会遇到这个问题。
事情是这样的。用户在划词翻译里可以选择付费使用翻译服务,后台里扣费的代码如下:
这段代码在生产环境运行到现在,直到我今天无意中发现一个问题:我同时开启了多个翻译服务,但只扣了一次费用。
细心的同学可能已经直到问题出在哪里了……
当用户同时启用了多个翻译服务时,客户端实际上同时发起了多个翻译请求,也就是说,控制台的日志是这样的:
这也就导致了为什么按照预期应该扣除 2 的场景下,最终结果却只扣除了 1……
本来以为作为一个前端来说,对于异步已经得心应手,但现在已经完全不敢有这个自信了 :joy: