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# -e MONGO_INITDB_ROOT_USERNAME=root -e MONGO_INITDB_ROOT_PASSWORD=123456
? ? ? ?如果運行上述命令后,mongodb容器處于退出狀態,請排查數據掛載目錄權限、配置文件問題、keyFile文件問題、27017端口沒有開放、容器占用系統太多資源導致系統資源不足等問題,可通過docker logs mongo查看具體原因。
5.查看mongodb存儲引擎和發行版本
# 查看mongodb版本
db.version()
# 查看當前數據庫的存儲引擎(需要root角色用戶)
db.serverStatus().storageEngine
6.初始化副本集和創建用戶
# 進入MongoDB容器
docker exec -it mongo mongosh
# 初始化副本集
rs.initiate({_id: "rs0",members: [{ _id: 0, host: "172.12.112.102:27017" }]
})
# 創建管理員用戶
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. 創建集合
use biobank
db.createUser({user: "test", pwd: "123456", roles: [{role: "readWrite", db: "printing"}]})
exitdocker exec -it mongo mongosh
use biobank
db.auth("test", "123456")
8.Flask-MongoEngine使用事務
? ? ? ?在 MongoDB 中,事務是通過會話(Session)來管理的。Flask-MongoEngine 本身不直接提供事務管理,但可以通過 PyMongo 的會話功能來實現。
MONGODB_SETTINGS = {'db': 'biobank','host': 'mongodb://test:123456@172.12.112.102:27017/biobank?replicaSet=rs0'
}# 或者
MONGODB_SETTINGS = {'host': '172.12.112.102','port': 27017,'username': 'test','password': '123456','db': 'biobank','authSource': 'biobank', # 指定身份驗證數據庫'replicaSet': 'rs0','connectTimeoutMS': 5000, # 設置套接字超時時間(毫秒)。'socketTimeoutMS': 30000, # 設置套接字超時時間(毫秒)。'serverSelectionTimeoutMS': 5000, # 設置服務器選擇超時時間(毫秒),當客戶端嘗試連接到 MongoDB 服務器時,如果在此時間內沒有找到可用的服務器,將拋出異常。'retryWrites': True, # 寫重試'retryReads': True # 讀重試
}
from flask import Flask
from flask_mongoengine import MongoEngine
from pymongo import MongoClient, ASCENDING
from pymongo.errors import OperationFailureapp = 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)