美文网首页
七、MongoDB中的事务

七、MongoDB中的事务

作者: 转身丶即天涯 | 来源:发表于2021-11-11 16:42 被阅读0次

理解事务

用过RDBMS的应该都知道,事务(Transaction)是一种“对于一连串的操作,要么都成功,要么都失败”的代名词。
事务其实是一个很大问题,这里不对原理做详细记录,网上一搜一堆。

Mongo中的事务

Mongo在4.0版本后引入事务的概念,大大增强了程序中多个关联操作的处理能力。

使用事务

接下来我会测试在python中应该如何使用事务。

为了方便清洗的阐述操作,我们在本地mongo数据库中新建两个集合(Set),分别叫user和company。
场景是,你要统计你的用户和用户所在公司的信息。

1. 在事务中操作多个文档(document)

from pymongo import MongoClient


client = MongoClient(host='localhost', port=27017)
db = client['my_test']
user_coll = db['user']
company_coll = db['company']

with client.start_session() as s:
    s.start_transaction()
    user_coll.insert({'name': 'nzh', 'age': 29})
    company_coll.insert({'company_name': 'my_company', 'address': 'shanghai'})
    s.commit_transaction()

client.close()

2. 在操作多个文档时,其中有一步是错误的

from pymongo import MongoClient


client = MongoClient(host='localhost', port=27017)
db = client['my_test']
user_coll = db['user']
company_coll = db['company']

with client.start_session() as s:
    s.start_transaction()
    user_coll.update({'name': 'nzh', 'age': 29}, {'$set': {'age': 30}})
    company_coll.insert({'error content'})
    s.commit_transaction()

client.close()

结果不尽人意,虽然过程报错了,但是nzh的age还是由29改为30了。
所以需要增加异常捕获,然后显式调用abort_transaction方法回滚操作。

from pymongo import MongoClient


client = MongoClient(host='localhost', port=27017)
db = client['my_test']
user_coll = db['user']
company_coll = db['company']

with client.start_session() as s:
    s.start_transaction()

    try:
        user_coll.update({'name': 'nzh', 'age': 30}, {'$set': {'age': 31}})
        company_coll.insert({'error content'})
    except Exception as e:
        s.abort_transaction()
        print(e)
    else:
        s.commit_transaction()
    finally:
        s.end_session()

client.close()

在查看结果时发现,虽然报错了,age还是由30变成了31.
说明abort_transaction方法仅仅是终止了session,并不带有回滚功能。
经过查资料发现,Mongo如果是单节点部署的话,是无法回滚的....

小结

我想要的功能并没有实现,现在需要部署Mongo的副本,才能实现事务回滚。
那么接下来需要学习如何部署副本了。

相关文章

网友评论

      本文标题:七、MongoDB中的事务

      本文链接:https://www.haomeiwen.com/subject/djqgzltx.html