MongoDB中ObjectId的误区,以及引起的一系列问题

误区 二 、多客户端高并发时,是否可以保证顺序(sort之后)?

如果一直保证写入远远大于读出(间隔一秒以上),这样是永远不会出现乱序的情况。

我们来看下样例

现在看到图中,取出数据两次

第一次

4df2dcec aaaa ffff 36a8b8134df2dcec aaaa eeee 36a8b8134df2dcec bbbb 1111 36a8b814

第二次

4df2dcec bbbb 1111 36a8b8134df2dcec aaaa ffff 36a8b8144df2dcec aaaa eeee 36a8b814

现在如果取第一次的最大值(4df2dcec bbbb 1111 36a8b814)做下次查询的结果,,那么就会漏掉

第二次的三条,因为(4df2dcec bbbb 1111 36a8b814)大于第二次取的所有记录。

所以会导致丢数据的情况。

解决办法:

由于ObjectId的时间戳截止到秒,而counter算子前四位又为机器与进程号。

1.处理一定时间间隔前的记录(一秒以上),这样即使机器和进程号导致乱序,间隔前也不会出现乱序情况。

2.单点插入,原来分布到几个点的插入操作,现在统一由一个点查询,保证机器与进程号相同,使用counter算子使记录有序。

这里,我们用到了第一种办法。

误区 三 、不在DBObject设置_id使用mongoDB设置ObjectId?mongoDB插入操作时,new DBBasicObject()时,大家看到_id是没有被填值的,除非手工的设置_id。那么是否是服务端设置的呢?

大家来看下插入操作的代码:

实现类

public WriteResult insert(List<DBObject> list, com.mongodb.WriteConcern concern, DBEncoder encoder ){if (concern == null) {throw new IllegalArgumentException("Write concern can not be null");}return insert(list, true, concern, encoder);}可以看到需要添加,默认都为添加

protected WriteResult insert(List<DBObject> list, boolean shouldApply , com.mongodb.WriteConcern concern, DBEncoder encoder ){if (encoder == null)encoder = DefaultDBEncoder.FACTORY.create();if ( willTrace() ) {for (DBObject o : list) {trace( "save: " + _fullNameSpace + " " + JSON.serialize( o ) );}}if ( shouldApply ){for (DBObject o : list) {apply(o);_checkObject(o, false, false);Object id = o.get("_id");if (id instanceof ObjectId) {((ObjectId) id).notNew();}}}WriteResult last = null;int cur = 0;int maxsize = _mongo.getMaxBsonObjectSize();while ( cur < list.size() ) {OutMessage om = OutMessage.insert( this , encoder, concern );for ( ; cur < list.size(); cur++ ){DBObject o = list.get(cur);om.putObject( o );// limit for batch insert is 4 x maxbson on server, use 2 x to be safeif ( om.size() > 2 * maxsize ){cur++;break;}}last = _connector.say( _db , om , concern );}return last;}自动添加ObjectId的操作 /*** calls {@link DBCollection#apply(com.mongodb.DBObject, boolean)} with ensureID=true* @param o <code>DBObject</code> to which to add fields* @return the modified parameter object*/public Object apply( DBObject o ){return apply( o , true );}/*** calls {@link DBCollection#doapply(com.mongodb.DBObject)}, optionally adding an automatic _id field* @param jo object to add fields to* @param ensureID whether to add an <code>_id</code> field* @return the modified object <code>o</code>*/public Object apply( DBObject jo , boolean ensureID ){Object id = jo.get( "_id" );if ( ensureID && id == null ){id = ObjectId.get();jo.put( "_id" , id );}doapply( jo );return id;}可以看到,mongoDB的驱动包中是会自动添加ObjectId的。

save的方法public WriteResult save( DBObject jo, WriteConcern concern ){if ( checkReadOnly( true ) )return null;_checkObject( jo , false , false );Object id = jo.get( "_id" );if ( id == null || ( id instanceof ObjectId && ((ObjectId)id).isNew() ) ){if ( id != null && id instanceof ObjectId )((ObjectId)id).notNew();if ( concern == null )return insert( jo );elsereturn insert( jo, concern );}DBObject q = new BasicDBObject();q.put( "_id" , id );if ( concern == null )return update( q , jo , true , false );elsereturn update( q , jo , true , false , concern );}

综上所述,默认情况下ObjectId是由客户端生成的,并不是不设置就由服务端生成的。

误区 四 、findAndModify是否真的可以获取到自增变量?DBObject update = new BasicDBObject("$inc", new BasicDBObject("counter", 1));DBObject query = new BasicDBObject("_id", key);DBObject result = getMongoTemplate().getCollection(collectionName).findAndModify(query, update);if (result == null){DBObject doc = new BasicDBObject();doc.put("counter", 1L);doc.put("_id", key);// insert(collectionName, doc);getMongoTemplate().save(doc, collectionName);return 1L;}return (Long) result.get("counter");获取自增变量会使用这种方法编写,但是,我们执行完成后会发现。

刺是与生俱来的,上帝在赐予优越感同时捆-绑的附属品;

MongoDB中ObjectId的误区,以及引起的一系列问题

相关文章:

  • 【算法】直接插入排序C语言实现
  • 嵌入式 FAAC1.28 在海思HI3518C/HI3518A平台linux中的编译优化
  • Android 动画animation 深入分析
  • Mybatis极其(最)简(好)单(用)的一个分页插件
  • Ext JS Kitchen Sink [Learning by doing](2)ArrayGrid
  • 你感兴趣的文章:

    标签云:

    亚洲高清电影在线, 免费高清电影, 八戒影院夜间, 八戒电影最新大片, 出轨在线电影, 午夜电影院, 在线影院a1166, 在线电影院, 在线观看美剧下载, 日本爱情电影, 日韩高清电影在线, 电影天堂网, 直播盒子app, 聚合直播, 高清美剧, 高清美剧在线观看 EhViewer-E站, E站, E站绿色版, qqmulu.com, qq目录网, qq网站目录,