从mgo迁移到mongo-go:session.Copy()替代方案问询
替代mgo session.Copy()的方案
核心差异先明确
mgo里的session.Copy()是用来创建共享连接池的轻量级会话,每个会话可独立配置读写模式、超时等参数。但在mongo-go驱动中,mongo.Client本身就是并发安全的,绝大多数场景下直接复用全局Client实例即可,无需复制类似session的对象。
普通CRUD场景:直接用Client操作
如果原代码仅用session.Copy()做独立的CRUD操作(无事务、无会话级特殊配置),直接用已初始化的mongo.Client执行操作即可,完全不需要额外创建会话:
// 原mgo代码 copySession := session.Copy() defer copySession.Close() err := copySession.DB("db").C("coll").Find(nil).All(&result) // mongo-go驱动替代写法 coll := client.Database("db").Collection("coll") cursor, err := coll.Find(context.TODO(), bson.M{}) if err != nil { // 错误处理 } defer cursor.Close(context.TODO()) err = cursor.All(context.TODO(), &result)
需要会话级控制的场景:使用StartSession
如果原代码用session.Copy()来实现会话级配置(比如自定义读写偏好、事务管理、独立上下文超时),则用client.StartSession()替代,它对应mgo中带自定义参数的会话复制逻辑:
1. 基础会话创建(对应单纯的session.Copy())
// 创建会话 session, err := client.StartSession() if err != nil { // 错误处理 } defer session.EndSession(context.TODO()) // 绑定会话到上下文,后续操作继承会话配置 ctx := mongo.NewSessionContext(context.TODO(), session) coll := client.Database("db").Collection("coll") cursor, err := coll.Find(ctx, bson.M{}) // ...后续业务逻辑
2. 带自定义选项的会话(比如读写偏好)
如果原代码中session.Copy()后设置了读写模式(如copySession.SetMode(mgo.Monotonic, true)),可在创建会话时直接指定选项:
opts := options.Session().SetReadPreference(readpref.SecondaryPreferred()) session, err := client.StartSession(opts) if err != nil { // 错误处理 } defer session.EndSession(context.TODO()) ctx := mongo.NewSessionContext(context.TODO(), session) // 后续所有操作都会遵循SecondaryPreferred的读偏好
3. 事务场景(mgo中用Copy()管理事务)
如果原代码用session.Copy()来处理事务,mongo-go驱动中会话是事务的载体,示例如下:
session, err := client.StartSession() if err != nil { // 错误处理 } defer session.EndSession(context.TODO()) // 启动事务 err = session.StartTransaction() if err != nil { // 错误处理 } ctx := mongo.NewSessionContext(context.TODO(), session) defer func() { r := recover() if r != nil || err != nil { _ = session.AbortTransaction(ctx) } else { _ = session.CommitTransaction(ctx) } }() // 执行事务内操作 coll := client.Database("db").Collection("coll") _, err = coll.InsertOne(ctx, bson.M{"key": "value"}) if err != nil { return err } // ...其他事务内操作
关键注意事项
mongo.Client是并发安全的,全局单例复用即可,无需每次操作都创建新ClientStartSession()创建的会话必须用EndSession()关闭,避免资源泄漏- 会话绑定的上下文
mongo.NewSessionContext()会自动传递会话的所有配置到后续操作中
内容的提问来源于stack exchange,提问作者dezdichado
相关产品推荐
相关产品推荐

