假设您正在制作一个聊天室应用程序,用户可以在其中设置昵称,但昵称对于聊天室必须是唯一的。我已经用这样的方法实现了这个:
Meteor.methods({
setNickname: function( nickname ) {
check( nickname, String );
if ( ! this.userId ) { /* throw error */ }
var chatroom = Chatroom.collection.findOne({
'users._id': this.userId
});
if ( _.findWhere( chatroom.users, { nickname: nickname } ) ) { /* throw error */ }
Chatroom.collection.update({
'users._id': this.userId,
}, {
$set: {
'users.$.nickname': nickname
}
});
}
});
这感觉很笨拙,我想知道验证逻辑与这样的查询分离是否可能存在并发问题。我想我可以将此逻辑移动到查询本身中,如下所示:
Meteor.methods({
setNickname: function( nickname ) {
check( nickname, String );
if ( ! this.userId ) { /* throw error */ }
Chatroom.collection.update({
'users._id': this.userId,
'users.nickname': {
$ne: nickname
}
}, {
$set: {
'users.$.nickname': nickname
}
});
}
});
我对 MongoDB 相当陌生,所以我不确定哪种方法更好。两种方法似乎工作原理相同,但我觉得如果两个用户尝试同时设置相同的昵称,第一种方法可以允许相同的昵称。
所以基本上,我应该使用复杂的更新选择器来确保此类操作是原子的吗?
最佳答案
一种方法是在 mongodb 中为昵称和聊天室 ID 设置唯一索引。这将防止违反该索引的插入或更新。如果您尝试插入当前存在的昵称,则必须捕获回调中的错误。
http://docs.mongodb.org/manual/tutorial/create-a-unique-index/
关于javascript - 在 Meteor 中使用复杂的更新选择器进行原子操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27031075/