uncategorized

Transaction In MongoDB

MongoDB

MongoDB中的事务可以对不同datebase、不同collection、不同document使用。

事务和锁

  • Transaction开始之前会请求需要用到的锁,在指定时间(默认5ms)内不能满足就会退出。
  • Transaction退出或提交后会释放持有的锁
  • 如果在Transaction开始之前要立即添加或删除collection,需要设置writeConcern为majority确保能获得相关的锁。

原子性

  • 事务在成功结束之前的所有修改在外部都不可见。
  • 事务失败后所有修改都会被忽略,同样外部不可见。

事务和ReadConcern/WriteConcern/ReadPreference

  • ReadConvern=local/majority不能保证重复读会得到一致的数据。
  • WriteConcern=majority时
    • ReadConcern=majority:能保证读取到多数节点确认的数据
    • ReadConcern=snapshot:能保证读取到多数节点确认的数据的快照
  • WriteConcern=其它时:不能保证上面的
  • 在事务中有读操作时,必须设置ReadPreference为主节点(primary)

写冲突机制

  • 如果事务正在执行,事务之外修改了某个文档,那么事务后面继续修改该文档时会退出。
  • 如果事务已经修改了该文档,外部的修改请求会等到事务结束后才执行。

过期的数据

如果事务正在执行,外部请求修改某个文档,由于事务使用了快照,读到的是该文档事务开始之前的状态。
解决办法:使用findAndUpdate来查询文档。这样外部请求先修改该文档时由于写冲突事务会退出;事务先查询该文档时会锁住该文档,事务结束后才执行外部请求。

事务重试

  • 事务失败时会返回错误,如果有errorLabels字段,且包含TransientTransactionError元素,那么这个事务可以重试。
  • 事务提交阶段失败时,同样返回错误,如果包含UnknownTransactionCommitResult元素,可以从事提交。

Tips

  • 4.0版本中Transaction不能对Shards使用,计划在4.2版本中支持事务
  • 事务只对WiredTiger存储引擎有效
  • 在事务中只能读写已经存在的collection
  • 不能读写config, admin, local数据库
  • 不能写system.*数据库
  • 不能返回某个操作符的查询计划
  • 不能创建/删除某个collection或索引
  • 不能使用非CRUD且非属性查询的操作
Share