假设您正在创建一个聊天室应用程序,用户可以在其中设置昵称,但昵称必须是聊天室唯一的。我用这样的方法实现了这个:
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很新,所以我不确定哪种方法更好。两种方式看起来都是一样的,但我觉得如果两个用户试图同时设置相同的昵称,第一种方式可以允许相同的昵称。
基本上,我应该使用复杂的更新选择器来确保这些操作是原子的吗?
答案 0 :(得分:1)
一种方法是在昵称和聊天室id上设置mongodb中的唯一索引。这样可以防止违反该索引的插入或更新。如果您尝试插入当前存在的昵称,则必须捕获回调中的错误。
http://docs.mongodb.org/manual/tutorial/create-a-unique-index/