以下是为本地开发环境设计的 MongoDB 集群搭建及事务操作指南,适用于需要事务支持(如批量插入、多步骤串行操作)的场景。
1. 为什么需要单机集群?
MongoDB 的事务功能仅支持副本集(Replica Set)或分片集群,单节点无法启用事务。通过 Docker 模拟多节点集群,可满足以下需求:
- 事务一致性:确保批量插入或复杂操作失败时自动回滚,例如:先下发配置再写入数据,中间步骤失败则全部撤销。
- 本地测试:避免依赖线上环境,降低调试成本。
- 轻量化:单机运行容器,资源占用可控。
2. Docker 搭建 MongoDB 单机集群
集群搭建需要keyfile进行节点认证,如果是采用windows上创建好key文件,然后再启动docker作宿主机目录映射,这个是有权限问题的,容器内对文件读取会报权限错误,这也是我踩的第一个坑,所以我们启动的时候采用bash启动,然后手动创建集群key文件,最后再手动启动mongd进程,下面是详细的安装步骤:
docker pull mongo:latestdocker run -tid --name mongo_test -e MONGO_INITDB_ROOT_USERNAME=mongo -e MONGO_INITDB_ROOT_PASSWORD=mongo -p 27018:27017 -v /d/Software/mongo/db:/data/db mongo:latest bash # 进到容器里
mkdir -p /home/mongodb-key/
cd /home/mongodb-key/
openssl rand -base64 756 > mongo.key
chmod 400 mongo.key
chown 999.999 mongo.keyls -l
# ----------- 1 mongodb mongdb 1024 May 14 02:12 mongo.key# 手动启动
mongod --bind_ip_all --auth --keyFile /home/mongodb-key/mongo.key -replSet rs0# 命令行配置
mongoshuse admin
db.auth("mongo", "mongo")# 配置集群
config = {_id:"rs0", version:1, members:[{_id:0, host:"127.0.0.1:27017", priority:1}]}
rs.initiate(config)rs.status()
mongo启动
rs.status()
mongo连接
3. Golang对mongodb进行增删改查
const(DBName = "my_db"TestColl = "my_coll"
)type MongoClient struct {mongoUrl stringclient *mongo.ClienttestColl *mongo.Collection
}func NewMongoClient(mongoUrl string) (*MongoClient, error) {serverAPI := options.ServerAPI(options.ServerAPIVersion1)opts := options.Client().ApplyURI(mongoUrl).SetServerAPIOptions(serverAPI)client, err := mongo.Connect(opts)if err != nil {return nil, err}// 数据库连接var result bson.Mif err := client.Database(DBName).RunCommand(context.TODO(), bson.D{{Key: "ping", Value: 1}}).Decode(&result); err != nil {return nil, err}return &MongoClient{mongoUrl: mongoUrl,client: client,connectorColl: client.Database(DBName).Collection(TestColl),}, nil
}func TestMongoConnectorCRDU(t *testing.T) {client, err := NewMongoClient("mongodb://mongo:mongo@localhost:27017/?replicaSet=rs0")require.NoError(t, err)require.NotNil(t, client)// 开启事务session, err := m.client.StartSession()require.NoError(t, err)defer session.EndSession(context.Background())err = session.StartTransaction()require.NoError(t, err)ctx := mongo.NewSessionContext(context.Background(), session)// 配置下发// TODO// 插入数据库A// TODO// 插入数据库B// TODO// 发生错误if err != nil {session.AbortTransaction(ctx) // 显式中止事务return }// 都成功了,再提交事务err = session.CommitTransaction(ctx)if err != nil {session.AbortTransaction(ctx) // 显式中止事务return }
}
Reference
https://blog.csdn.net/shuidi5273/article/details/104912026
https://www.mongodb.com/zh-cn/docs/languages/go/