遇到问题----MongoDB---JAVA-

发布时间:2017-6-29 10:49:29编辑:www.fx114.net 分享查询网我要评论
本篇文章主要介绍了"遇到问题----MongoDB---JAVA-",主要涉及到遇到问题----MongoDB---JAVA-方面的内容,对于遇到问题----MongoDB---JAVA-感兴趣的同学可以参考一下。



现象

这与MongoDB内部执行顺序的有关。


先说下我们的场景。数据库中有大量的数据需要 重新 更新。


我们使用的是java驱动,mongotemplate.save如果文档存在,则只会更新文档。


因为数据单个文档 的结构很复杂, 我们担心使用save不能正确的更新文档所以使用了关系型数据库上的操作逻辑。


就是在逻辑层,java操作中 执行先删除原文档再保存新文档(id)保持一致。


如果保存的文档 大小很大的时候是不会有问题的。


但是保存的文档太小时,大批量操作中 会出现 保存操作比 删除操作执行得快的情况。


我们期望的执行顺序应该是:


删除数据库中 编号为1的数据 ----->  保存 编号为1的数据


而现在出现的顺序为


保存 编号为1的数据  ----->  删除数据库中 编号为1的数据


导致了 保存的数据也被删除了。


原因

MongoDB与关系型数据库不同,MongoDB没有事务,所以 删除与保存 不是一个原子操作。


而且MongoDB的操作不关心 执行 是否成功。一般驱动中不提供操作返回值。


也就是说 对MongoDB发出指令后,它不会等待它返回结果才执行下一个指令,这样MongoDB的速度就很快,但也给我们带来了一些问题。


虽然 mongotemplate.remove比mongotemplate.save先发出(间隔估计只有0.2,总之间隔很短),但是在数据库层接收到指令时,有可能save会比remove执行得快,尤其是大数据量和加了索引等复杂情况下。




解决方案

后来调研了mongoTemplate.save方法,发现它是可靠的。

其实mongoTemplate.save方法在数据库层执行的 逻辑就是  先删除原文档再保存新文档。

而不是 每个字段去对比更新。

这样就不担心 复杂文档结构 更新 不一致了。


调研方法 

先保存

{"id":ObjectId("334232"),"filed1":1,"filed2":2}


然后使用 

save({"id":ObjectId("334232"),"filed1":new1});


如果save是每个字段去对比更新的话,就会变成

{"id":ObjectId("334232"),"filed1":new1,"filed2":2}


实际上文档变成了

{"id":ObjectId("334232"),"filed1":new1}


所以证明save并不是每个字段去对比更新。

而是当id相同时把原文档删除后保存新文档,id保持一致。



 也就是说 我们要 更新文档时,可以直接使用save方法即可,而不需要先remove再save。





 






上一篇:实用的 CSS — 贝塞尔曲线(cubic
下一篇:WMS系统开发总结

相关文章

相关评论

本站评论功能暂时取消,后续此功能例行通知。

一、不得利用本站危害国家安全、泄露国家秘密,不得侵犯国家社会集体的和公民的合法权益,不得利用本站制作、复制和传播不法有害信息!

二、互相尊重,对自己的言论和行为负责。

好贷网好贷款