遇到问题----MongoDB---JAVA--大批量操作先删后存时偶尔出现保存的文档也被删除
2017-06-16 10:46
573 查看
现象
这与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。
相关文章推荐
- python操作mongoDB的时候遇到问题,find()结果无法保存
- java操作MongoDB遇到的一些问题
- java中利用dom4j对XML文档的创建、解析、查找、修改、保存等操作。
- java操作FTP时遇到的问题小结
- 文档无法保存。读取文档时出现问题(135)
- 遇到问题----struts2文件下载出现Can not find a java.io.InputStream with the name的错误
- 20140918遇到的问题------JAVA------MyEclipse配置Tomcat出现的问题
- 怎样用java语言屏蔽pdf文档中的复制、打印、保存操作啊?请教高手
- 关于MFC中数据库操作中遇到的问题:Microsoft C++ 在xxx内存处出现问题_com_error的另一解决方案
- 解决struts/spring偶尔出现java.lang.IllegalStateException: Cannot call sendRedirect() after the response的问题
- java工程项目里,在一个包里面,不能出现同名的类名,这问题是刚接触java才会遇到的,特别是新手一般都没有建立包,而是使用默认的,易出现同名的类名,导致eclipse提示错误
- 遇到问题----struts2文件下载出现Can not find a java.io.InputStream with the name的错误
- 遇到的问题-----c#操作mongodb用foreach遍历集合报错curcor not found
- 尝试加载 Oracle 客户端库时引发 BadImageFormatException。如果在安装 32 位 Oracle 客户端组件的情况下以 64 位模式运行,将出现此问题。(遇到了这个问题网上查了下保存下来)
- java中利用dom4j对XML文档的创建、解析、查找、修改、保存等操作。
- java操作word文档 表格带有边框 乱码 问题
- mongoDB——java操作mongodb文档
- 遇到的问题------java读写txt出现乱码
- java操作数据库出现(][SQLServer 2000 Driver for JDBC]Error establishing socket.)的问题所在即解决办法
- java读取txt文档遇到的问题