Mongodb事务

Mongodb的事务通常是指多文档之间,Mongodb从4.0版本开始支持副本集的多行多文档事务,4.2版本开始支持分布式事务,增加了分片集群上多行多文档事务的支持。

关系型数据库事务属性mongodb支持程度
Atomocity 原子性        

单表单文档 1.x开始支持
复制集群多表多行:4.0

分片集群多表多行:4.2

Consistency一致性writeConcern,readConcern (3.2开始)
Isolation 隔离性readConcern (3.2开始)
Durability 持久性Journal and replication

 

Write Concern

 writeConcern决定一个写操作落到多少个节点上才算成功,writeConcern的取值包括:

  • w:0 设置为0 无需关心写入成功与否
  • w :1-任意节点数,最大数为复制集群节点数,默认为1 ,表示写到Primary节点就开始往客户端发送确认写入成功。
  • w:majority 大多数节点成功原则,非具体数据,复制集群中的大多数。
  • w:all 所有节点写入成功才算成功
  • j:true 默认情况为false,写操作达到内存算完成,如果设置为j:true,写操作只有到达journal文件才算成功。
  • wtimeout:写入超时实战

测试示例

writeConcern: {
    w:"majority" // 大多数
    j:true,
    wtimeout: 6000,
}

建议:重要数据设置 w:"majority" 保证数据不丢失,普通数据设置w:1保证最优性能

 Read Preference

readPreference决定使用哪一个节点来满足 正在发起的读请求。可选值包括:
  • primary: 只选择主节点;
  • primaryPreferred:优先选择主节点,如果不可用选择从节点
  • secondary:只选择从节点
  • secondaryPreferred:优先选择从节点,如果从节点不可用则选择主节点;
  • nearest:选择最近的节点;

primary/primaryPreferred:适合于数据实时性要求较高的场景,例如,订单创建完毕直接跳转到订单详情,如果选择从节点读取,可能会造成主节点数据写入之后,从节点还未复制的情况,因为复制过程是一个异步的操作。
secondary/secondaryPreferred:适应用于数据实时性要求不高的场景,例如,报表数据、历史订单。还可以减轻对主节点的压力。

配置示例

mongodb://mongodb0.example.com:27017,mongodb1.example.com:27017,mongodb2.example.com:27017/admin?replicaSet=myRepl&readPreference=secondary

 Read Concern

MongoDB 3.2 引入了 readConcern 来决定读取的策略,但是与 readPreference 不同,readPreference 决定从哪个节点读取,readConcern 决定该节点的哪些数据是可读的。主要保证事务中的隔离性,避免脏读。可选值如下:

  • available:读取所有可用的数据;
  • local:读取所有可用且属于当前分片的数据,默认设置
  • majority:读取在大多数节点上提交完成的数据;
  • linearizable:可线性化读取文档;只对读取单个文档时有效;
  • snapshot:读取最近快照中的数据;最高隔离级别,接近于 Seriazable,只在多文档事务中生效

使用示例:

在启动 Mongod 实例时,指定 --enableMajorityReadConcern 选项或在配置文件中配置

enableMajorityReadConcern=true

使用示例

db.user.find().readConcern("majority")

MongoDB 的 readConcern 默认情况下是脏读,例如,用户在主节点读取一条数据之后,该节点未将数据同步至其它从节点,就因为异常挂掉了,待主节点恢复之后,将未同步至其它节点的数据进行回滚,就出现了脏读。

从主节点读取数据时默认 readConcern 是 local,从从节点读取数据时默认
readConcern 是 available(向前兼容原因)。

MongoDB <=3.6 不支持对从节点使用 {readConcern: "local"};

readConcern 级别的 majority 可以保证读到的数据已经落入到大多数节点。所以说保证了事务的隔离性,所谓隔离性也是指事务内的操作,事务外是看不见的。

在复制集中 local 和 available 是没有区别的。两者的区别主要体现在分片集上。考虑以下场景:

一个 chunk x 正在从 shard1 向 shard2 迁移
整个迁移过程中 chunk x 中的部分数据会在 shard1 和 shard2 中同时存在,但源分片 shard1仍然是chunk x 的负责方:
所有对 chunk x 的读写操作仍然进入 shard1; 
config 中记录的信息 chunk x 仍然属于 shard1;
此时如果读 shard2,则会体现出 local 和 available 的区别:
local:只取应该由 shard2 负责的数据(不包括 x);
available:shard2 上有什么就读什么(包括 x);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值