1.mogodb支持事务的前提
1) MongoDB 版本:确保 MongoDB 版本大于或等于 4.0,因为事务支持是在 4.0 版本中引入的。
2) 副本集配置:MongoDB 必须以副本集(Replica Set)模式运行,即使是单节点副本集(即只有一个 MongoDB 实例,但以副本集模式启动)。
2.安装docker
3.创建目录和文件
1) 宿主机-mongodb的数据存储目录
mkdir /mongo/data
chmod 777 /mongo/data
2) 宿主机-mongodb的配置文件目录
mkdir /mongo/conf
chmod 777 /mongo/conf
3) 宿主机-mongodb的密钥文件
cd /mongo
openssl rand -base64 756 > keyFile
chmod 400 keyFile # 一定是400,不要赋权777
chown 999:999 keyFile
4) 在/mongo/conf目录下,生成配置文件mongod.conf
# 存储配置
storage:
dbPath: /data/db # 数据库文件存储路径
engine: wiredTiger # 存储引擎(通常为 wiredTiger)
wiredTiger:
engineConfig:
cacheSizeGB: 1 # WiredTiger 缓存大小(单位:GB)
directoryForIndexes: true # 是否为索引使用单独目录
# 网络配置
net:
port: 27017 # MongoDB 监听端口
bindIp: 0.0.0.0 # 绑定 IP 地址(0.0.0.0 表示监听所有网络接口)
# 安全配置
security:
authorization: enabled # 是否启用认证
keyFile: /data/mongodb/keyFile # 密钥文件路径(用于副本集或分片集群)
# 副本集配置(如果使用副本集)
replication:
replSetName: "rs0" # 副本集名称
4.启动MongoDB容器
docker run -d --name mongo -p 27017:27017 \
-v /mongo/data:/data/db \
-v /mongo/conf/mongod.conf:/etc/mongod.conf \
-v /mongo/keyFile:/data/mongodb/keyFile \
mongo:latest mongod --auth --bind_ip_all --config /etc/mongod.conf
如果运行上述命令后,mongodb容器处于退出状态,请排查数据挂载目录权限、配置文件问题、keyFile文件问题、27017端口没有开放、容器占用系统太多资源导致系统资源不足等问题,可通过docker logs mongo查看具体原因。
5.查看mongodb存储引擎和发行版本
# 查看mongodb版本
db.version()
# 查看当前数据库的存储引擎(需要root角色用户)
db.serverStatus().storageEngine
6.初始化副本集和创建用户
# 进入MongoDB容器
docker exec -it mongo mongosh
# 初始化副本集
rs.initiate()
# 创建管理员用户
use admin
db.createUser({
user: 'admin',
pwd: 'admin123456',
roles: [{role: 'userAdminAnyDatabase', db: 'admin'}]})
# 创建root用户
db.createUser({
user: "root",
pwd: "123456",
roles: [{ role: "root", db: "admin" }]
})
# 验证用户
db.auth("admin", "admin123456")
db.auth("root", "123456")
7.Flask-MongoEngine使用事务
在 MongoDB 中,事务是通过会话(Session)来管理的。Flask-MongoEngine 本身不直接提供事务管理,但可以通过 PyMongo 的会话功能来实现。
from flask import Flask
from flask_mongoengine import MongoEngine
from pymongo import MongoClient, ASCENDING
from pymongo.errors import OperationFailure
app = Flask(__name__)
# 配置 MongoDB 连接
app.config["MONGODB_SETTINGS"] = {
'db': 'your_database_name',
'host': 'mongodb://localhost:27017/'
}
db = MongoEngine(app)
# 定义一个简单的模型
class MyModel(db.Document):
name = db.StringField(required=True)
value = db.IntField(required=True)
@app.route('/transaction_example', methods=['GET'])
def transaction_example():
# 获取 PyMongo 客户端
client = MongoClient(app.config["MONGODB_SETTINGS"]['host'])
session = client.start_session()
try:
with session.start_transaction():
# 在事务中执行操作
MyModel(name='example', value=1).save(session=session)
# 可以在这里执行更多操作,它们将在同一个事务中
# 如果任何操作失败,整个事务将回滚
session.commit_transaction()
return "Transaction committed successfully."
except OperationFailure as e:
# 如果事务失败,回滚
session.abort_transaction()
return f"Transaction aborted: {e}"
finally:
session.end_session()
if __name__ == '__main__':
app.run(debug=True)