当我在NODE.JS中快速多次按下按钮时,会出现奇怪的行为
我有两张有两名候选人的卡片,每个候选人都有一个按钮,用户可以在其中进行唯一的投票,卡片上还有一个框,框中有total投票,如果用户投票给第一位候选人,那么两张卡片中total的值都会被更新(在一张卡片中减去另一张卡片中添加的值)。但是,当我多次快速按下按钮时,后端返回的数据是不正确的。请有人解释一下发生了什么事当我在NODE.JS中快速多次按下按钮时,会出现奇怪的行为,node.js,angular,Node.js,Angular,我有两张有两名候选人的卡片,每个候选人都有一个按钮,用户可以在其中进行唯一的投票,卡片上还有一个框,框中有total投票,如果用户投票给第一位候选人,那么两张卡片中total的值都会被更新(在一张卡片中减去另一张卡片中添加的值)。但是,当我多次快速按下按钮时,后端返回的数据是不正确的。请有人解释一下发生了什么事 角形零件的模板 NODE.JS中的控制器 数据库 const VoteSchema = Schema({ user:{ type:Schema.Object
角形零件的模板
NODE.JS中的控制器
数据库
const VoteSchema = Schema({
user:{
type:Schema.ObjectId,
ref:'User',
required:[true, 'User is required - vote user']
},
thisChoosed:{
type:Boolean,
default:false
},
firstVote:{
type:Boolean,
default:true
}
})
const CandidateSchema = Schema({
names:{
type:String,
required:[true]
},
surnames:{
type:String,
required:[true]
},
userVotes:[VoteSchema],
totalVotes:{
type:Number,
default:0
},
})
预期的结果是候选人中的子步骤1和另一个中的添加1,但当我快速按下按钮多次时,结果是(0-2),(-1,4)或(-2,5),例如,您有一个竞争条件。您正在执行两个数据库操作,一个接一个。但是,其他大约在同一时间到达并影响数据库相同部分的请求可能会进入它们之间,并打乱您的预期结果,从而导致其他一些影响两个请求之间相同部分数据的DB操作。我对你的数据库不太了解,不知道该怎么做。典型的解决方案包括一个排序队列、一个临时数据库锁、一个事务、将所有内容装配到一个原子数据库操作中等等。根据这个链接(),我无法手动锁定数据库,mongodb锁。在文档中,我们解释了可以锁定数据库、集合或文档,但它们不是示例。顺便问一下,我在这个问题中添加了我的数据库,您遇到的问题到底是什么?结果
res.json(newVote)
是从最后一次数据库调用开始的-如果紧接着另一个DB调用并更改了值,则不能保证它是当前的。请准确描述您观察到的问题以及您预期的结果。并且,描述这是一个数据库完整性问题还是仅仅是一个显示问题?数据库中每个候选人的初始投票状态:TotalVoces:1---TotalVoces:0。投票后的所需状态:TotalVoces:2---TotalVoces:0。该问题只需多次按下按钮:TotalVoces:4---TotalVoces:-1。问题出在数据库中。我需要为每个候选人保持正确的总投票状态,尽管要收到该领域的许多更新。
export class CandidatesContainerComponent implements OnInit {
candidates!: any[]
constructor(
private candidatesService: CandidatesService,
) { }
ngOnInit(): void {
this.obtainCandidates()
}
obtainCandidates() {
this.candidatesService.getCandidates().subscribe((response: any) => {
this.candidates = response
})
}
saveVote(userVote: any, candidate: object | any) {
this.candidatesService.updateVote(candidate._id, userVote.thisChoosed).subscribe(response => {
if (response) {
this.obtainCandidates()
}
})
}
}
const updateVote = async ( req = request, res = response ) => {
const { candidateId, thisChoosed } = req.params
const query = thisChoosed === 'true' ? candidateId: { $ne:candidateId }
const previousVote = await Candidate.findOneAndUpdate(
{ _id:query },
{
'$set': { 'userVotes.$[el].thisChoose': false },
'$inc': { 'totalVotes': -1 }
},
{ arrayFilters: [
{"el.user": req.user._id }]
}
)
const newVote = await Candidate.findOneAndUpdate(
{ _id:candidateId },
{
'$set': { 'userVotes.$[el].thisChoose': true },
'$inc': { 'totalVotes': 1 }
},
{
arrayFilters: [ {"el.user": req.user._id }, ], new:true
}
)
res.json( newVote )
}
const VoteSchema = Schema({
user:{
type:Schema.ObjectId,
ref:'User',
required:[true, 'User is required - vote user']
},
thisChoosed:{
type:Boolean,
default:false
},
firstVote:{
type:Boolean,
default:true
}
})
const CandidateSchema = Schema({
names:{
type:String,
required:[true]
},
surnames:{
type:String,
required:[true]
},
userVotes:[VoteSchema],
totalVotes:{
type:Number,
default:0
},
})