当前位置:数据库 > mongodb >>

MongoDB之insert"安全操作"

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()返回的值也紧跟着变化。貌似两个客户端使用的是同一个游标。
 
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,