MongoDB的原子性和多文档事务处理

        原子性和事务处理是数据库操作的核心,保证了数据的准确性。依据数据库原子性,数据库和使用数据库的人员定义事务处理的方式。本文依据Mongodb的官方文档,整理Mongodb数据库的原子性和事务处理方法。

Mongodb的原子操作

        Mongodb中,对单个文档的操作是原子的,即使一次文档更新中,更新了文档的多个嵌入文档,这个更新操作也是原子操作。

        当文档写入更新语句更新多个文档时,该操作不是原子的。如使用updateMany更新多个文档,insertMany向集合中插入多条数据,这样的操作都不是原子的。mongodb在执行过程中,mongodb会将多文档插入更新转化为单文档插入更新操作,保证每个文档的操作是原子的,并为每个单一文档操作添加操作日志。多文档操作更新数据的过程中,其他写操作有机会穿插进来。

多文档事务

        为了保证多文档事务的原子性,mongodb给出了多文档事务解决方案。

  • 在mongodb 4.0版本,mongodb 复制集支持多文档事务
  • 在mongodb4.2及以后版本,mongodb引入的分布式事务,添加了分片集群和复制集群的事务支持。通过分布式事务管理,mongodb能够保证跨文档,跨集合,跨数据库和不同数据库分片的操作事务管理。

        多文档事务是原子性的。当事务提交时,所有在事务中修改的文档都会被保存,更新后的数据对事务外部可见。如果事务中的部分操作需要回滚,整个事务中的操作都不会被提交。事务中所有需要更新的数据保持不变。

        借助多文档事务,开发人员保证数据操作的原子性。但操作多文档事务,与操作单文档相比,数据库性能会受到更大的影响。从数据库设计角度来说,多文档事务的支持,不应该成为更合理高效数据结构定义的替代品。大多数场景中,应该通过持续优化非标准的数据结构(数组和对象)定义来减少多文档事务。减少数据库操作等待时间,提高数据库效率。

事务中的操作

        下面列出了事务中允许和禁止的操作

  • 对已有集合的读写操作。如CRUD操作,集合操作等。
  • 4.4版本开始,在非分片集合事务中,可以添加集合并为新添加的集合创建索引
    • 允许隐式创建集合,如使用insert方法,向不存在的集合中插入数据。使用update、findAndModify操作不存在的集合,设置{upsert:true}
    • 显示创建集合,如使用create、db.createCollection() 命令创建集合
    • 事务中添加的索引,只能够为该事务中添加的空集合创建索引,或为不存在的集合添加索引,但该集合需要在本事务中创建。
    • 不可以为分片数据集事务添加集合
    • 分片数据集中,不可以使用操作符$graphLookup
    • 事务中显示的添加集合和创建索引,事务读取策略需要设置为本地(local)
  • 事务中允许操作来自不同数据库的集合
  • 禁止为包含多个分片数据集的事务添加新集合,如果开发人员在一个分片中写数据,在另一个分片中隐式添加新的集合,mongodb事务中并不会执行这两个操作
  • 不可以在限制集合中写入数据
  • 读取限制集合数据时,不可以使用snapshot读取策略。使用“snapshot”策略时, mongodb只能获取到不同分片区上一次majority-committed提交的数据
  • 事务中不可以读写config, admin, local数据库中的集合
  • 禁止向system.*集合写入数据。system.*是mongodb保留数据集合
  • 事务中不支持查看执行计划,不能在查询语句中使用explain()
  • 事务外部创建的cursor, 不可以在事务内部调用getMore()方法获取下一批查询数据
  • 事务内部创建的cursor, 不可以在事务外部调用getMore()方法
  • 自版本4.2开始,事务中第一步,不可以使用killCursors命令
  • 多文档事务中,禁止使用创建删除集合和索引这种对已有数据库结构有影响的操作。但允许操作事务中添加新的集合和索引。

你可能感兴趣的:(mongodb,mongodb,数据库)