首页 > 代码库 > Mongdb 脏读
Mongdb 脏读
读隔离(New in version 3.2.):
readConcern: { level: <"majority"|"local"|"linearizable"> }
readConcern选项可用于以下操作:
- find command
- aggregate command and the db.collection.aggregate() method
- distinct command
- count command
- parallelCollectionScan command
- geoNear command
- geoSearch command
用于副本集和副本集分片的readConcern查询选项确定从查询返回哪些数据。
readConcern级别:
"local":默认。 该查询返回实例的最新数据。 不保证数据已写入大多数副本集成员(即可以回滚)。
"majority":该查询会将实例的最新数据确认为已写入副本集中的大多数成员。要使用majority级别,您必须使用--enableMajorityReadConcern命令行选项启动mongod实例(如果使用配置文件,则将replication.enableMajorityReadConcern设置为true)。
"linearizable"(add in version3.4):该查询返回反映所有成功写入的数据。
这么说 如果配置了linearizable 那么针对一个集合的查询就可以避免脏读了。因为Mongdb没有事务,所以也就不存在幻读和不可重复读的定义了。不过这个功能是在当前最新的3.4版本才有的。
还有一种方法,使用db.collection.findAndModify()来避免脏读:
当从副本集读取数据时,可能会读取数据过时(即可能不反映在读取操作之前发生的所有写入)或不持久的数据(即数据的状态可能反映尚未写入的数据) 。从版本3.4开始,MongoDB引入了"线性化"readConcern,返回不过时的持久数据。
这里还有替代过程,使用db.collection.findAndModify()读取不过时且不能回滚的数据,在MongoDB 3.2之后可用。
db.collection.findAndModify的约束:
db.collection.findAndModify()使用完全匹配查询,并且必须存在唯一索引才能满足查询。
findAndModify()必须实际修改一个文档; 即导致文件的更改。
findAndModify()必须使用写入concern { w: "majority" }.
- db.products.insert( [
- {
- _id: 1,
- sku: "xyz123",
- description: "hats",
- available: [ { quantity: 25, size: "S" }, { quantity: 50, size: "M" } ],
- _dummy_field: 0
- },
- {
- _id: 2,
- sku: "abc123",
- description: "socks",
- available: [ { quantity: 10, size: "L" } ],
- _dummy_field: 0
- },
- {
- _id: 3,
- sku: "ijk123",
- description: "t-shirts",
- available: [ { quantity: 30, size: "M" }, { quantity: 5, size: "L" } ],
- _dummy_field: 0
- }
- ] )
- db.products.createIndex( { sku: 1 }, { unique: true } )
- var updatedDocument = db.products.findAndModify(
- {
- query: { sku: "abc123" },
- update: { $inc: { _dummy_field: 1 } },
- new: true,
- writeConcern: { w: "majority", wtimeout: 5000 }
- }
- );
Mongdb 脏读