mongodb支持事务吗么

多文档事务满足ACID的原子性

? 当一个事务被提交时,该事务内部中所有的变更都会保存并且可以被其他会话的事务读到。

  • 当事务回滚时,事务内部所有的变更都会被干净的丢弃。比如,事务中的任一操作失败后,事务回滚,当前事务中所有的变更都会被丢弃,且不为其他会话所知。

多文档事务中的读操作必须使用primary倾向性,即从复制集的主实例

多文档事务支持三种读一致性等级: , , and ,即快照,本机,多数派

? 针对本机和多数派的读一致性等级,MongoDB在有些时候回使用更强的等级进行替换。(注:为啥?)

  • 针对多数派读一致性等级,如果事务使用此级别进行提交,事务操作都会读到副本集中多数派已经提交的数据。

  • 针对快照级别的读一致性,如果。。。。。【官方文档这儿是不是写错了】,如果事务使用快照级别的读一致性进行提交,那么可以保证事务中的操作读到的都是事务开始时的多数派事务快照。

如果针对当前事务设置读一致性,而不是对事务中的独立操作设置一致性,那该一致性会覆盖事务中所有的事务。而且在事务中,事务粒度的一致性会覆盖集合级别,数据库级别,客户端级别的读一致性。

可以在事务开始时对读一致性进行设置。

如果缺省了事务级别的读一致性设置,事务会继承会话级别的读一致性,如果会话级别也没有设置读一致性,那么会继续向上继承客y户端层级设置的读一致性。

如果针对当前事务设置写一致性,而不是对事务中的独立操作设置一致性。那么在提交时,事务会使用自身的一致性去提交写操作。事务中各个独立操作忽略写一致性,请不要徒劳设置。(注:这段原文语义模糊,这里认为本段原文与上段原文写法不同,是为了和上段中的情况进行区分)

可以在事务开始时对读一致性进行设置。

? 如果缺省了事务级别的写一致性设置,那么事务在提交时会继承会话级别的写一致性,会话级别也缺省了设置的话,会继续向上继承客户端级别的写一致性。

  • 进行提交,那么该事务提交时只会确认本机oK,也就是PrimaryOK。如果主节点挂掉,且该事务没有被传输到当时的次级节点。那么,恭喜你,该事务大概率会被回滚掉。会造成数据库端和应用端数据的不一致和数据缺失。

  • 如果事务使用多数派写一致性进行提交,且指定了快照级别的读一致性。那么事务操作会确保从事务开始时多数派已经提交的快照数据中进行读取。(注:这段语义不明,官方文档到底在表达什么,是不是写错了)

  • 如果事务使用多数派写一致性进行提交,且指定了多数派级别的读一致性,那么事务中的操作会被确保从多数派已提交的数据中进行读取。(注:这个是不是官方文档编辑时复制粘贴错了,把上面读一致性的内容放过来了)

事务中的操作在获取其所需要数据上的锁时,默认等待超时时间为5毫秒,超时后,当前事务会被回滚。(注:这个太短了吧,幸好可以手动设置)

如果在创建或者删除集合后会紧接着开启一个会对该集合进行操作的事务,那么创建或者删除集合的操作需要追加写一致性(writeConcern)扩散到多数节点的参数以确保事务可以成功获取该集合相关的锁。

(注,这段话可能较为拗口。其实是从集群的一致性来考虑,和事务的读一致性readConcern相关)

参数对锁等待超时长度进行设置。

设为-1,以禁用锁等待超时回滚,该事务会一直等待自己所需要的锁被其他事务或者会话释放。

mongodb 4.0已经支持副本集级别的事务了,而且现在是稳定版.下一个版本4.2准备支持分片的事物.我因为数据库规模较小,暂时用不到分片的规模,于是就先升级到4.0版本.

提醒: mongo官方建议你不要把事务当救命稻草, 更多的时候要依赖良好的设计模式来减少使用多文档事务的机会,毕竟事务是会影响性能的.

首先贴出官方文档,鸟语好的同学可以直接啃生肉.

先备份数据库,虽说升级后数据库会保留下来,但为了不要最后演变成删库闹剧.还是老老实实的备份数据库吧

  1. mongodb3.6要求,如果你不满足这个条件(比如你是3.4版本),那么请先升级到3.6的版本.
  2. 兼容性检查,取消了一些特性,如果你当前的系统用到了这些特性,恐怕你要一些额外的工作,具体的兼容性检查信息在

由于我用的是ubuntu16.04我就用这个系统来演示.

    注意,安装之前必须先停止mongodb的服务,否则会提示安装成功但仍然是原来的3.6版本

接下来,让我们测试一下.

  1. 数据库必须工作在副本集或者分片模式.单机模式是不支持事务的. 这点不是问题,把单机转换为只有一个成员的副本集就好了.另外,如果你的兼容性检查显示的是3.6版本的话也不行.

事务不向下兼容,必须把兼容性提高到4.0

  1. 多文档事务执行的时候,不会自动创建命名空间. 也就是说,如果你的collection还未建立的话, 你执行事务的时候会报错.
  1. 如果你出现下面的这样的错误
"localThresholdMS": 30, # 本地超时的阈值,默认是15ms,服务器超过此时间没有返回响应将会被排除在可用服务器范围之外 "maxPoolSize": 100, # 最大连接池,默认100,不能设置为0,连接池用尽后,新的请求将被阻塞处于等待状态. """自定义单例模式客户端连接池"""

事务必须运行在一个clientSession的session周期内.嵌套了2个with.这只是个示范,生产环境请自行封装.

这种操作在mongodb中用事务好,还是加锁好?
发布于 3 个月前 作者 883 次浏览 来自 问答

假设集合A中有文档a1,集合B中有文档b1 如果a1中的field1字段大于10,则更新b1文档,否则啥也不做。


我现在的做法是对a1文档加锁,然后再进行查询a1(加锁和查询一条语句),修改b1,最后释放锁 缺点:1. 所有涉及到修改a1的地方都要加锁,2. 有可能死锁

现在mongodb支持事务了,我想用事务将查询和修改这两个操作包起来,但感觉大材小用了,各位有什么建议吗?

我要回帖

更多关于 mongodb支持事务吗 的文章

 

随机推荐