mongo 中的事务(一)

MongoDB中的事务

注意:mongo version 4.2

因为mongo db 里面的文档是可以内嵌,一般对於单个集合(表)一般用不到事务,
然而对于多个集合、多个文档、多个数据库甚至于多个分片进行操作的时候就需要用到分布式事务
也就是多文档事务

首先看一个例子: 官网例子

# For a replica set, include the replica set name and a seedlist of the members in the URI string; e.g.
# uriString = 'mongodb://mongodb0.example.com:27017,mongodb1.example.com:27017/?replicaSet=myRepl'
# For a sharded cluster, connect to the mongos instances; e.g.
# uriString = 'mongodb://mongos0.example.com:27017,mongos1.example.com:27017/'
from pymongo import *


uriString = 'mongodb://mongodb0.example.com:27017,mongodb1.example.com:27017/?replicaSet=myRepl'
client = MongoClient(uriString)
wc_majority = WriteConcern("majority", wtimeout=1000)

# Prereq: Create collections. CRUD operations in transactions must be on existing collections.
client.get_database(
    "mydb1", write_concern=wc_majority).foo.insert_one({'abc': 0})
client.get_database(
    "mydb2", write_concern=wc_majority).bar.insert_one({'xyz': 0})

# Step 1: Define the callback that specifies the sequence of operations to perform inside the transactions.
def callback(session):
    collection_one = session.client.mydb1.foo
    collection_two = session.client.mydb2.bar

    # Important:: You must pass the session to the operations.
    collection_one.insert_one({'abc': 1}, session=session)
    collection_two.insert_one({'xyz': 999}, session=session)

# Step 2: Start a client session.
with client.start_session() as session:
    # Step 3: Use with_transaction to start a transaction, execute the callback, and commit (or abort on error).
    session.with_transaction(
        callback, read_concern=ReadConcern('local'),
        write_concern=wc_majority,
        read_preference=ReadPreference.PRIMARY)

上面例子主要是展示了:

  1. 事务操作的集合要存在
  2. 事务操作要在同一个会话里面

同时mongo分布式事务还有以下特性:

  1. 事务提交之前,事务之内的数据改变对于其他操作不可见
  2. 对于多个shard上的事务,某一个shard上事务提交之后不需要等待其他分片事务提交,
    这一分片上事务内的数据更改可以对本地读外部可见,
  3. 事务内的操作全部成功才会提交,否则其他未生效数据更改将被丢弃

事务里面操作的一些限制:

  1. 集合必须存在
  2. 不能操作特殊数据库config、admin、local
  3. 不能操作sys数据库下所有集合和固定集合
  4. 不能返回执行计划
  5. 游标操作需要在其事务范围内

特别注意:建索引、创建集合等对集合本身的操作也不允许

总结来说: 就是事务内的操作不应涉及到集合的操作,包括因数据插入导致固定集合去删除一部分内容, 只可以是增删改查以及有限的获取信息集合

额外:
isMaster, buildInfo, connectionStatus允许在事务中但不能在第一个操作

发布了131 篇原创文章 · 获赞 153 · 访问量 34万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章