首页 > 代码库 > 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" }.

 

  1. db.products.insert( [
  2.    {
  3.      _id: 1,
  4.      sku: "xyz123",
  5.      description: "hats",
  6.      available: [ { quantity: 25, size: "S" }, { quantity: 50, size: "M" } ],
  7.      _dummy_field: 0
  8.    },
  9.    {
  10.      _id: 2,
  11.      sku: "abc123",
  12.      description: "socks",
  13.      available: [ { quantity: 10, size: "L" } ],
  14.      _dummy_field: 0
  15.    },
  16.    {
  17.      _id: 3,
  18.      sku: "ijk123",
  19.      description: "t-shirts",
  20.      available: [ { quantity: 30, size: "M" }, { quantity: 5, size: "L" } ],
  21.      _dummy_field: 0
  22.    }
  23. ] )
  24.  
  25. db.products.createIndex( { sku: 1 }, { unique: true } )
  26.  
  27. var updatedDocument = db.products.findAndModify(
  28.    {
  29.      query: { sku: "abc123" },
  30.      update: { $inc: { _dummy_field: 1 } },
  31.      new: true,
  32.      writeConcern: { w: "majority", wtimeout: 5000 }
  33.    }
  34. );

Mongdb 脏读