单机模拟MongoDB测试集群与Go应用集成

以下是为本地开发环境设计的 MongoDB 集群搭建及事务操作指南,适用于需要事务支持(如批量插入、多步骤串行操作)的场景。

1. 为什么需要单机集群?

MongoDB 的事务功能仅支持副本集(Replica Set)或分片集群 ,单节点无法启用事务。通过 Docker 模拟多节点集群,可满足以下需求:

  1. 事务一致性:确保批量插入或复杂操作失败时自动回滚,例如:先下发配置再写入数据,中间步骤失败则全部撤销。
  2. 本地测试:避免依赖线上环境,降低调试成本。
  3. 轻量化:单机运行容器,资源占用可控。

2. Docker 搭建 MongoDB 单机集群

集群搭建需要keyfile进行节点认证,如果是采用windows上创建好key文件,然后再启动docker作宿主机目录映射,这个是有权限问题的,容器内对文件读取会报权限错误,这也是我踩的第一个坑,所以我们启动的时候采用bash启动,然后手动创建集群key文件,最后再手动启动mongd进程,下面是详细的安装步骤:

bash 复制代码
docker pull mongo:latest

docker 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.key

ls -l
# ----------- 1 mongodb mongdb 1024 May 14 02:12 mongo.key

# 手动启动
mongod --bind_ip_all  --auth --keyFile /home/mongodb-key/mongo.key -replSet rs0

# 命令行配置
mongosh

use 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进行增删改查

go 复制代码
const(
    DBName   = "my_db"
    TestColl = "my_coll"
)

type MongoClient struct {
	mongoUrl string

	client       *mongo.Client
	testColl     *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.M
	if 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

blog.csdn.net/shuidi5273/...

www.mongodb.com/zh-cn/docs/...

相关推荐
野犬寒鸦2 分钟前
从零起步学习MySQL || 第九章:从数据页的角度看B+树及MySQL中数据的底层存储原理(结合常见面试题深度解析)
java·服务器·数据库·后端·mysql·oracle·1024程序员节
IT_陈寒2 分钟前
SpringBoot 3.2 实战:这5个新特性让你的开发效率提升50%!
前端·人工智能·后端
Victor35620 分钟前
Redis(82)如何解决Redis的缓存雪崩问题?
后端
Victor35622 分钟前
Redis(83)Redis的缓存击穿是什么?
后端
码事漫谈25 分钟前
从LIS到全院区多活:浙江省人民医院“信创样板”全景复盘
后端
Jing_jing_X26 分钟前
Spring Boot 启动时,JVM 是如何工作的?
java·后端·spring·1024程序员节
thinktik7 小时前
AWS EKS安装S3 CSI插件[AWS 海外区]
后端·kubernetes·aws
Tony Bai10 小时前
【Go 网络编程全解】12 本地高速公路:Unix 域套接字与网络设备信息
开发语言·网络·后端·golang·unix
Yeats_Liao11 小时前
Go Web 编程快速入门 06 - 响应 ResponseWriter:状态码与头部
开发语言·后端·golang
mit6.82411 小时前
[Agent可视化] 编排工作流(Go) | Temporal引擎 | DAG调度器 | ReAct模式实现
开发语言·后端·golang