douqiu0796 2015-09-25 17:56
浏览 64

在go中同时使用相同的mgo会话

So I'm having some trouble figuring out best practices for using concurrency with a MongoDB in go. My first implementation of getting a session looked like this:

var globalSession *mgo.Session

func getSession() (*mgo.Session, error) {
    //Establish our database connection
    if globalSession == nil {
        var err error
        globalSession, err = mgo.Dial(":27017")
        if err != nil {
            return nil, err
        }

        //Optional. Switch the session to a monotonic behavior.
        globalSession.SetMode(mgo.Monotonic, true)
    }

    return globalSession.Copy(), nil
}

This works great the trouble I'm running into is that mongo has a limit of 204 connections then it starts refusing connections connection refused because too many open connections: 204;however, the issue is since I'm calling session.Copy() it only returns a session and not an error. So event though the connection refused my program never thrown an error.

Now what I though about doing is just having one session and using that instead of copy so I can have access to a connection error like so:

var session *mgo.Session = nil

func NewSession() (*mgo.Session, error) {
    if session == nil {
        session, err = mgo.Dial(url)
        if err != nil {
            return nil, err
        }
    }

    return session, nil
}

Now the problem I have with this is that I don't know what would happen if I try to make concurrent usage of that same session.

  • 写回答

1条回答 默认 最新

  • douzhuang2016 2018-04-03 18:37
    关注

    The key is to duplicate the session and then close it when you've finished with it.

    func GetMyData() []myMongoDoc {
    
        sessionCopy, _ := getSession() // from the question above
        defer sessionCopy.Close() // this is the important bit
    
        results := make([]myMongoDoc, 0)
        sessionCopy.DB("myDB").C("myCollection").Find(nil).All(&results)
        return results
    }
    

    Having said that it looks like mgo doesn't actually expose control over the underlying connections (see the comment from Gustavo Niemeyer who maintains the library). A session pretty much equates to a connection, but even if you call Close() on a session mgo keeps the connection alive. From reading around it seems that Clone() might be the way to go, as it reuses the underlying socket, this will avoid the 3 way handshake of creating a new socket (see here for more discussion on the difference).

    Also see this SO answer describing a standard pattern to handle sessions.

    评论

报告相同问题?

悬赏问题

  • ¥30 这是哪个作者做的宝宝起名网站
  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!