MongoDB之insert"安全操作"
?
MongoDB中插入、删除、更新操作都是瞬间完成的,它们都不需要等待
数据库响应。默认采用的不是“安全”模式的。
?
01
#-*- coding:UTF-8 -*-
02
'''
03
Created on 2013-9-20
04
05
@author: tyk
06
'''
07
from pymongo import Connection
08
import time
09
10
def save1():
11
conn = Connection('localhost', 27017) #获取一个连接
12
conn.drop_database('test1')
13
db = conn.test1
14
t = db.T
15
for i in range(1, 100000):
16
#t.insert({'num': i }, w = 1)
17
t.insert({'num': i })
18
19
def save2():
20
with open('LICENSE') as f:
21
data = f.read()#读取文本,将其更新到文档中
22
conn = Connection('localhost', 27017) #获取一个连接
23
db = conn.test1
24
t = db.T
25
print t.count()
26
#db.collection.find().snapshot()
27
for n in t.find(timeout=False):#查询出来所有的文档,遍历
28
t.update({'_id': n['_id']}, {'$set':{'data':data}})
29
print n['num']
30
31
if __name__ == '__main__':
32
save1()
33
#time.sleep(10)
34
save2()
?
实验一 :(第二天在此模拟时始终无法出现以下结果!)
save1()首先插入
?
1
t.insert({'num': i })
紧接着save2()进行查询
1
for n in t.find(timeout=False):#查询出来所有的文档,遍历
2
t.update({'_id': n['_id']}, {'$set':{'data':data}})
?
打印结果:
第一次:
?
1
1
2
{u'_id': ObjectId('5255593d06d80e0c601502af'), u'num': 1}
3
{u'_id': ObjectId('5255593d06d80e0c601502b0'), u'num': 2}
?
?
第二次:
?
1
2
2
{u'_id': ObjectId('5255593d06d80e0c601502af'), u'num': 1}
3
{u'_id': ObjectId('5255593d06d80e0c601502b0'), u'num': 2}
?
实验二:
save1()和save2()之间sleep(10)
?
?
打印结果:
?
1
999999
2
{u'_id': ObjectId('5255593d06d80e0c601502af'), u'num': 1}
3
{u'_id': ObjectId('5255593d06d80e0c601502b0'), u'num': 2}
4
......
?
实验三:
采用安全模式进行插入(python驱动建议以‘w’取代‘safe’)
?
1
t.insert({'num': i }, w = 1)
打印结果:
1
999999
2
{u'_id': ObjectId('5255593d06d80e0c601502af'), u'num': 1}
3
{u'_id': ObjectId('5255593d06d80e0c601502b0'), u'num': 2}
4
?
......
?
?
疑问:
?
本次实验本来是为了解决上次一个问题“一个客户端进行更新时(对文档结构产出较大变化的更新),另一个客户端进行一次find()后更新操作立刻停止,貌似一直发生阻塞。针对这个问题的猜想可能是文档发生大规模移动,使用游标可能就会有一些问题(参考《MongoDB权威指南》 4.5.5 获取一致结果 一章),本来想在进行插入时另一客户端查询时使用快照db.T.find({},{'num':1}).snapshot()查询。但是这次并没有明显出现阻塞问题。
?
1.实验不严谨,更新对文档产生较大影响要发生移动时MongoDB会有学习功能,会为每个文档预留相应的空间。这次更新文档为同一篇文章,大小一样。也可能只在第一次发生了一次大规模移动,后续的预留空间都够存储文档了。有待进一步验证
?
2.前一天实验中在后续的查询Insert和find结果是不一致的,必须借助于"安全操作"才可以同步。但是在后来实验中没有使用"安全操作"再也不出现这种情况了?
?
3.在实验中在另一客户端采用find()和find().snapshot()两次查出来的文档是不一样的。
?
? ? find()
?
?
? ? find({},{'num':1}).snapshot()
?
?
使用快照查询返回的是按照插入顺序返回的,而直接使用find()查询返回的都是还没更新的文档(data字段还没更新上),后来根据更新时同步打印的记录显示直接调用find()返回的就是另一客户端将要更新的文档,随着逐步更新,find()返回的值也紧跟着变化。貌似两个客户端使用的是同一个游标。
?
?