由于有批量操作的需求,看了一下这个 Bulk API,看完之后有几个问题。
当前为了实现 bulk insert,我自己定义了一个 List, 每次有新数据要插入的时候,将数据转换成合适的格式,放进这个 List 里,等需要的时候执行 insert(List) 操作。这相当于我自己维护了一个缓存队列,而且这种队列还需要考虑到线程安全。从 Bulk.insert() 的 API 来看,只是把数据直接 insert 到这个 bulk 里。
我想问的是:
1.Bulk 是不是自己在客户端维护了一个缓存队列?如果是的话,它的线程安全性有保障吗?
2.有了 Bulk 之后,是不是我不需要自己去维护我的缓存队列,交给 Bulk 去做就可以了?
3.Bulk 是用 db.collection.initializeOrderedBulkOp() 方法获得的。测试了一下发现,我似乎必须得长期持有这个方法返回的引用,否则无法用其他方法再重新获得缓存队列中的数据。那么,如果长期持有的话,是不是在 execute() 之前会保持着一个长连接?那如果连接断掉呢?
这个取决于驱动的实现。mongodb的API并不规定这个线程安全性(如Javascript驱动就没有线程)。从你的描述中估计你用的是Java。在Java驱动里面 Bulk API用的是ArrayList所以理论上线程安全没有保障。不过你在调用的一般就是insert(),相当于 ArrayList.add(),实际使用中多线程同时调用add()并没有太多问题。
如果安全一点的话,就像你所做的一样,使用一个线程安全List,自己来维护这个队列,最后一次性交给MongoDB驱动来execute。
关于第3个问题,这个和连接没有直接的关系。bulk操作可以使用一个,也可以对不同操作使用连接池内的不同连接(bulk操作内部会对所有操作按类型进行分组,每个组都是自己的一个网络请求)。不一定是一个长连接。如果连接断掉,对于orderedBulkOp 这个bulk操作就会失败并终止;对于unorderedBulkOp,会忽略错误并继续剩下的操作。
另外, 上述讨论针对于2.6。 2.4或以前会有所不同。
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。