MongoDB 的事务实现

116 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第13天,点击查看活动详情

我们之前了解到,MongoDB不支持事务,因此在开发时候需要使用事务,就要借助其他方法,比如在业务代码层面弥补数据库不足。但是随着MongoDB 4.0 的发布,引入了多文档事务的支持,为多文档事务提供了 "all-or-nothing" 的原子操作,可以用于多个操作、集合、数据库和文档。

那么 MongoDB 中事务的实现。

在 MongoDB 4.2 引入了分布式事务,增加了对分片集群上多文档事务的支持,并合并了对副本集上多文档事务的现有支持。

这里所说的多文档事务是原子的(即提供“全有或全无”的主张):

  • 当事务提交时,事务中所做的所有数据更改都将保存并在事务外部可见,也就是说,事务不会在回滚其他更改时提交其某些更改。
  • 在事务提交之前,事务中所做的数据更改在事务之外是不可见的。但是事务写入多个分片时,并非所有外部读取操作都需要等待已提交事务的结果在分片中可见。
  • 当事务中止时,事务中所做的所有数据更改都将被丢弃,而不会变得可见。

事务和会话

这里大家需要知道,MongoDB 中的事务和会话(Sessions)是关联的,一个会话同一时刻只能开启一个事务操作,当一个会话断开,这个会话中的事务也会结束。

事务中的函数

MongoDB 中如果使用事务的话,会使用到下面几个函数:

  • Session.startTransaction():在当前会话中开始一次事务,事务开启后就可以开始进行数据操作。在事务中执行的数据操作是对外隔离的,也就是说事务中的操作是原子性的。

  • Session.commitTransaction():提交事务,将事务对数据的修改进行保存,然后结束当前事务,一次事务在提交之前的数据操作对外都是不可见的。

  • Session.abortTransaction():中止当前的事务,并将事务中执行的数据修改回滚。 具体操作如下所示:

  • 获取会话(Session) 对象

    s=db.getMongo().startSession()
    
  • 开启事务

    s.startTransaction()
    
  • 添加数据

    s.getDatabase("lanqiao").lq1.insert({name:"yangguo",age:24})
    
    s.getDatabase("lanqiao").lq2.insert({name:"xiaolongnv",age:24})
    
  • 提交(回滚)事务

    提交事务

    s.commitTransaction()
    

    回滚事务

    s.abortTransaction()